Browse Source

Merge remote-tracking branch 'Mavlink/master' into MavlinkLogUploader

* Mavlink/master:
  Only run unit tests on pull requests
  MAVLink: Update to most recent spec
  PX4 param and airframe metadata update (#4169)
  Don't apply throttle deadband in ThrottleModeDownZero
  Use FTDI driver provided by ftdicjip.com
  AppImage update to libsdl2 (#4155)
  Minor formatting fix
  Added a second polygon. This polygon is updated from the first polygon at each mouse click and is what will ultimately be saved upon completion of drawing.
  Fixed a bug where a black line would be rendered when starting to draw a polygon.
  Fix brand image visibility calculation
  Remove FileManager unit test
  VTOL text change
  Update VTOL command text
  Update message
  Temp removal of Onboard File
  Changing label
  Making deadbands stupid-proof; general cleanup
  Cleanup & Sync
  Implementing throttle axis accumulator with deadband support
  Handle redirects in file downloads
QGC4.4
Gus Grubba 9 years ago
parent
commit
c862245d34
  1. 14
      .travis.yml
  2. BIN
      android/libs/d2xx.jar
  3. 36
      android/res/xml/device_filter.xml
  4. 345
      android/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java
  5. 22
      android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java
  6. 16
      android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java
  7. 3
      deploy/create_linux_appimage.sh
  8. 2
      libs/mavlink/include/mavlink/v1.0
  9. 2
      libs/mavlink/include/mavlink/v2.0
  10. 69
      libs/qtandroidserialport/src/qserialport_android.cpp
  11. 3
      libs/qtandroidserialport/src/qserialport_android_p.h
  12. 5
      src/AutoPilotPlugins/PX4/AirframeComponent.qml
  13. 183
      src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml
  14. 1296
      src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml
  15. 30
      src/FlightMap/FlightMap.qml
  16. 86
      src/Joystick/Joystick.cc
  17. 18
      src/Joystick/Joystick.h
  18. 10
      src/MissionManager/MavCmdInfoCommon.json
  19. 60
      src/VehicleSetup/JoystickConfig.qml
  20. 75
      src/VehicleSetup/JoystickConfigController.cc
  21. 24
      src/VehicleSetup/JoystickConfigController.h
  22. 4
      src/qgcunittest/UnitTestList.cc
  23. 12
      src/ui/MainWindow.cc
  24. 4
      src/ui/toolbar/MainToolBar.qml

14
.travis.yml

@ -174,12 +174,14 @@ script:
#- ccache -s #- ccache -s
# unit tests linux/osx # unit tests linux/osx
- if [[ "${SPEC}" = "linux-g++-64" && "${CONFIG}" = "debug" ]]; then - if [ "${TRAVIS_BRANCH}" != "master" ]; then
mkdir -p ~/.config/QtProject/ && cp ${TRAVIS_BUILD_DIR}/test/qtlogging.ini ~/.config/QtProject/ && if [[ "${SPEC}" = "linux-g++-64" && "${CONFIG}" = "debug" ]]; then
./debug/QGroundControl --unittest; mkdir -p ~/.config/QtProject/ && cp ${TRAVIS_BUILD_DIR}/test/qtlogging.ini ~/.config/QtProject/ &&
elif [[ "${SPEC}" = "macx-clang" && "${CONFIG}" = "debug" ]]; then ./debug/QGroundControl --unittest;
mkdir -p ~/Library/Preferences/QtProject/ && cp ${TRAVIS_BUILD_DIR}/test/qtlogging.ini ~/Library/Preferences/QtProject/ && elif [[ "${SPEC}" = "macx-clang" && "${CONFIG}" = "debug" ]]; then
./debug/qgroundcontrol.app/Contents/MacOS/QGroundControl --unittest; mkdir -p ~/Library/Preferences/QtProject/ && cp ${TRAVIS_BUILD_DIR}/test/qtlogging.ini ~/Library/Preferences/QtProject/ &&
./debug/qgroundcontrol.app/Contents/MacOS/QGroundControl --unittest;
fi
fi fi
after_success: after_success:

BIN
android/libs/d2xx.jar

Binary file not shown.

36
android/res/xml/device_filter.xml

@ -1,40 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Everything --> <!-- Allow anything connected -->
<usb-device /> <usb-device />
<!-- 0x26AC / 0x11: PX4 FMU Pixhawk -->
<!--
<usb-device vendor-id="9900" product-id="17" />
-->
<!-- 0x0403 / 0x6001: FTDI FT232R UART -->
<!--
<usb-device vendor-id="1027" product-id="24577" />
-->
<!-- 0x0403 / 0x6015: FTDI FT231X -->
<!--
<usb-device vendor-id="1027" product-id="24597" />
-->
<!-- 0x2341 / Arduino -->
<!--
<usb-device vendor-id="9025" />
-->
<!-- 0x16C0 / 0x0483: Teensyduino -->
<!--
<usb-device vendor-id="5824" product-id="1155" />
-->
<!-- 0x10C4 / 0xEA60: CP210x UART Bridge -->
<!--
<usb-device vendor-id="4292" product-id="60000" />
-->
<!-- 0x067B / 0x2303: Prolific PL2303 -->
<!--
<usb-device vendor-id="1659" product-id="8963" />
-->
</resources> </resources>

345
android/src/com/hoho/android/usbserial/driver/FtdiSerialDriver.java

@ -18,6 +18,10 @@
* Project home page: http://code.google.com/p/usb-serial-for-android/ * Project home page: http://code.google.com/p/usb-serial-for-android/
*/ */
// IMPORTANT NOTE:
// This code has been modified from the original source. It now uses the FTDI driver provided by
// ftdichip.com to communicate with an FTDI device. The previous code did not work with all FTDI
// devices.
package com.hoho.android.usbserial.driver; package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbConstants;
@ -27,12 +31,16 @@ import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbRequest; import android.hardware.usb.UsbRequest;
import android.util.Log; import android.util.Log;
import com.ftdi.j2xx.D2xxManager;
import com.ftdi.j2xx.FT_Device;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import org.qgroundcontrol.qgchelper.UsbDeviceJNI;
/** /**
* A {@link CommonUsbSerialDriver} implementation for a variety of FTDI devices * A {@link CommonUsbSerialDriver} implementation for a variety of FTDI devices
* <p> * <p>
@ -167,6 +175,8 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
*/ */
private static final boolean ENABLE_ASYNC_READS = false; private static final boolean ENABLE_ASYNC_READS = false;
FT_Device m_ftDev;
/** /**
* Filter FTDI status bytes from buffer * Filter FTDI status bytes from buffer
* @param src The source buffer (which contains status bytes) * @param src The source buffer (which contains status bytes)
@ -219,261 +229,140 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
@Override @Override
public void open() throws IOException { public void open() throws IOException {
boolean opened = false; D2xxManager ftD2xx = null;
try { try {
for (int i = 0; i < mDevice.getInterfaceCount(); i++) { ftD2xx = D2xxManager.getInstance(UsbDeviceJNI.m_context);
if (mConnection.claimInterface(mDevice.getInterface(i), true)) { } catch (D2xxManager.D2xxException ex) {
Log.d(TAG, "claimInterface " + i + " SUCCESS"); UsbDeviceJNI.qgcLogDebug("D2xxManager.getInstance threw exception: " + ex.getMessage());
} else { }
throw new IOException("Error claiming interface " + i);
} if (ftD2xx == null) {
} String errMsg = "Unable to retrieve D2xxManager instance.";
reset(); UsbDeviceJNI.qgcLogWarning(errMsg);
opened = true; throw new IOException(errMsg);
}
UsbDeviceJNI.qgcLogDebug("Opened D2xxManager");
int DevCount = ftD2xx.createDeviceInfoList(UsbDeviceJNI.m_context);
UsbDeviceJNI.qgcLogDebug("Found " + DevCount + " ftdi devices.");
if (DevCount < 1) {
throw new IOException("No FTDI Devices found");
}
m_ftDev = null;
try {
m_ftDev = ftD2xx.openByIndex(UsbDeviceJNI.m_context, 0);
} catch (NullPointerException e) {
UsbDeviceJNI.qgcLogDebug("ftD2xx.openByIndex exception: " + e.getMessage());
} finally { } finally {
if (!opened) { if (m_ftDev == null) {
close(); throw new IOException("No FTDI Devices found");
} }
} }
UsbDeviceJNI.qgcLogDebug("Opened FTDI device.");
} }
@Override @Override
public void close() { public void close() {
mConnection.close(); if (m_ftDev != null) {
try {
m_ftDev.close();
} catch (Exception e) {
UsbDeviceJNI.qgcLogWarning("close exception: " + e.getMessage());
}
m_ftDev = null;
}
} }
@Override @Override
public int read(byte[] dest, int timeoutMillis) throws IOException { public int read(byte[] dest, int timeoutMillis) throws IOException {
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(0); int totalBytesRead = 0;
int bytesAvailable = m_ftDev.getQueueStatus();
if (ENABLE_ASYNC_READS) {
final int readAmt; if (bytesAvailable > 0) {
synchronized (mReadBufferLock) { bytesAvailable = Math.min(4096, bytesAvailable);
// mReadBuffer is only used for maximum read size. try {
readAmt = Math.min(dest.length, mReadBuffer.length); totalBytesRead = m_ftDev.read(dest, bytesAvailable, timeoutMillis);
} } catch (NullPointerException e) {
final String errorMsg = "Error reading: " + e.getMessage();
final UsbRequest request = new UsbRequest(); UsbDeviceJNI.qgcLogWarning(errorMsg);
request.initialize(mConnection, endpoint); throw new IOException(errorMsg, e);
final ByteBuffer buf = ByteBuffer.wrap(dest);
if (!request.queue(buf, readAmt)) {
throw new IOException("Error queueing request.");
}
final UsbRequest response = mConnection.requestWait();
if (response == null) {
throw new IOException("Null response");
}
final int payloadBytesRead = buf.position() - MODEM_STATUS_HEADER_LENGTH;
if (payloadBytesRead > 0) {
return payloadBytesRead;
} else {
return 0;
}
} else {
final int totalBytesRead;
synchronized (mReadBufferLock) {
final int readAmt = Math.min(dest.length, mReadBuffer.length);
totalBytesRead = mConnection.bulkTransfer(endpoint, mReadBuffer,
readAmt, timeoutMillis);
if (totalBytesRead < MODEM_STATUS_HEADER_LENGTH) {
throw new IOException("Expected at least " + MODEM_STATUS_HEADER_LENGTH + " bytes");
}
return filterStatusBytes(mReadBuffer, dest, totalBytesRead, endpoint.getMaxPacketSize());
} }
} }
return totalBytesRead;
} }
@Override @Override
public int write(byte[] src, int timeoutMillis) throws IOException { public int write(byte[] src, int timeoutMillis) throws IOException {
final UsbEndpoint endpoint = mDevice.getInterface(0).getEndpoint(1); try {
int offset = 0; m_ftDev.write(src);
return src.length;
while (offset < src.length) { } catch (Exception e) {
final int writeLength; UsbDeviceJNI.qgcLogWarning("Error writing: " + e.getMessage());
final int amtWritten;
synchronized (mWriteBufferLock) {
final byte[] writeBuffer;
writeLength = Math.min(src.length - offset, mWriteBuffer.length);
if (offset == 0) {
writeBuffer = src;
} else {
// bulkTransfer does not support offsets, make a copy.
System.arraycopy(src, offset, mWriteBuffer, 0, writeLength);
writeBuffer = mWriteBuffer;
}
amtWritten = mConnection.bulkTransfer(endpoint, writeBuffer, writeLength,
timeoutMillis);
}
if (amtWritten <= 0) {
throw new IOException("Error writing " + writeLength
+ " bytes at offset " + offset + " length=" + src.length);
}
//Log.d(TAG, "Wrote amtWritten=" + amtWritten + " attempted=" + writeLength);
offset += amtWritten;
} }
return offset; return 0;
} }
private int setBaudRate(int baudRate) throws IOException { private int setBaudRate(int baudRate) throws IOException {
long[] vals = convertBaudrate(baudRate); try {
long actualBaudrate = vals[0]; m_ftDev.setBaudRate(baudRate);
long index = vals[1]; return baudRate;
long value = vals[2]; } catch (Exception e) {
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, UsbDeviceJNI.qgcLogWarning("Error setting baud rate: " + e.getMessage());
SIO_SET_BAUD_RATE_REQUEST, (int) value, (int) index,
null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Setting baudrate failed: result=" + result);
} }
return (int) actualBaudrate; return 0;
} }
@Override @Override
public void setParameters(int baudRate, int dataBits, int stopBits, int parity) public void setParameters(int baudRate, int dataBits, int stopBits, int parity) throws IOException {
throws IOException {
setBaudRate(baudRate); setBaudRate(baudRate);
int config = dataBits; switch (dataBits) {
case 7:
switch (parity) { dataBits = D2xxManager.FT_DATA_BITS_7;
case PARITY_NONE: break;
config |= (0x00 << 8); case 8:
break; default:
case PARITY_ODD: dataBits = D2xxManager.FT_DATA_BITS_8;
config |= (0x01 << 8); break;
break;
case PARITY_EVEN:
config |= (0x02 << 8);
break;
case PARITY_MARK:
config |= (0x03 << 8);
break;
case PARITY_SPACE:
config |= (0x04 << 8);
break;
default:
throw new IllegalArgumentException("Unknown parity value: " + parity);
} }
switch (stopBits) { switch (stopBits) {
case STOPBITS_1: default:
config |= (0x00 << 11); case 0:
break; stopBits = D2xxManager.FT_STOP_BITS_1;
case STOPBITS_1_5: break;
config |= (0x01 << 11); case 1:
break; stopBits = D2xxManager.FT_STOP_BITS_2;
case STOPBITS_2: break;
config |= (0x02 << 11);
break;
default:
throw new IllegalArgumentException("Unknown stopBits value: " + stopBits);
}
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE,
SIO_SET_DATA_REQUEST, config, 0 /* index */,
null, 0, USB_WRITE_TIMEOUT_MILLIS);
if (result != 0) {
throw new IOException("Setting parameters failed: result=" + result);
} }
}
private long[] convertBaudrate(int baudrate) { switch (parity) {
// TODO(mikey): Braindead transcription of libfti method. Clean up, default:
// using more idiomatic Java where possible. case 0:
int divisor = 24000000 / baudrate; parity = D2xxManager.FT_PARITY_NONE;
int bestDivisor = 0; break;
int bestBaud = 0; case 1:
int bestBaudDiff = 0; parity = D2xxManager.FT_PARITY_ODD;
int fracCode[] = { break;
0, 3, 2, 4, 1, 5, 6, 7 case 2:
}; parity = D2xxManager.FT_PARITY_EVEN;
break;
for (int i = 0; i < 2; i++) { case 3:
int tryDivisor = divisor + i; parity = D2xxManager.FT_PARITY_MARK;
int baudEstimate; break;
int baudDiff; case 4:
parity = D2xxManager.FT_PARITY_SPACE;
if (tryDivisor <= 8) { break;
// Round up to minimum supported divisor
tryDivisor = 8;
} else if (mType != DeviceType.TYPE_AM && tryDivisor < 12) {
// BM doesn't support divisors 9 through 11 inclusive
tryDivisor = 12;
} else if (divisor < 16) {
// AM doesn't support divisors 9 through 15 inclusive
tryDivisor = 16;
} else {
if (mType == DeviceType.TYPE_AM) {
// TODO
} else {
if (tryDivisor > 0x1FFFF) {
// Round down to maximum supported divisor value (for
// BM)
tryDivisor = 0x1FFFF;
}
}
}
// Get estimated baud rate (to nearest integer)
baudEstimate = (24000000 + (tryDivisor / 2)) / tryDivisor;
// Get absolute difference from requested baud rate
if (baudEstimate < baudrate) {
baudDiff = baudrate - baudEstimate;
} else {
baudDiff = baudEstimate - baudrate;
}
if (i == 0 || baudDiff < bestBaudDiff) {
// Closest to requested baud rate so far
bestDivisor = tryDivisor;
bestBaud = baudEstimate;
bestBaudDiff = baudDiff;
if (baudDiff == 0) {
// Spot on! No point trying
break;
}
}
}
// Encode the best divisor value
long encodedDivisor = (bestDivisor >> 3) | (fracCode[bestDivisor & 7] << 14);
// Deal with special cases for encoded value
if (encodedDivisor == 1) {
encodedDivisor = 0; // 3000000 baud
} else if (encodedDivisor == 0x4001) {
encodedDivisor = 1; // 2000000 baud (BM only)
} }
// Split into "value" and "index" values try {
long value = encodedDivisor & 0xFFFF; m_ftDev.setDataCharacteristics((byte)dataBits, (byte)stopBits, (byte)parity);
long index; } catch (Exception e) {
if (mType == DeviceType.TYPE_2232C || mType == DeviceType.TYPE_2232H UsbDeviceJNI.qgcLogWarning("Error setDataCharacteristics: " + e.getMessage());
|| mType == DeviceType.TYPE_4232H) {
index = (encodedDivisor >> 8) & 0xffff;
index &= 0xFF00;
index |= 0 /* TODO mIndex */;
} else {
index = (encodedDivisor >> 16) & 0xffff;
} }
// Return the nearest baud rate
return new long[] {
bestBaud, index, value
};
} }
@Override @Override
public boolean getCD() throws IOException { public boolean getCD() throws IOException {
return false; return false;
@ -515,18 +404,22 @@ public class FtdiSerialDriver extends CommonUsbSerialDriver {
@Override @Override
public boolean purgeHwBuffers(boolean purgeReadBuffers, boolean purgeWriteBuffers) throws IOException { public boolean purgeHwBuffers(boolean purgeReadBuffers, boolean purgeWriteBuffers) throws IOException {
if (purgeReadBuffers) { if (purgeReadBuffers) {
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, try {
SIO_RESET_PURGE_RX, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS); m_ftDev.purge(D2xxManager.FT_PURGE_RX);
if (result != 0) { } catch (Exception e) {
throw new IOException("Flushing RX failed: result=" + result); String errMsg = "Error purgeHwBuffers(RX): "+ e.getMessage();
UsbDeviceJNI.qgcLogWarning(errMsg);
throw new IOException(errMsg);
} }
} }
if (purgeWriteBuffers) { if (purgeWriteBuffers) {
int result = mConnection.controlTransfer(FTDI_DEVICE_OUT_REQTYPE, SIO_RESET_REQUEST, try {
SIO_RESET_PURGE_TX, 0 /* index */, null, 0, USB_WRITE_TIMEOUT_MILLIS); m_ftDev.purge(D2xxManager.FT_PURGE_TX);
if (result != 0) { } catch (Exception e) {
throw new IOException("Flushing RX failed: result=" + result); String errMsg = "Error purgeHwBuffers(TX): " + e.getMessage();
UsbDeviceJNI.qgcLogWarning(errMsg);
throw new IOException(errMsg);
} }
} }

22
android/src/com/hoho/android/usbserial/driver/UsbSerialProber.java

@ -18,6 +18,10 @@
* Project home page: http://code.google.com/p/usb-serial-for-android/ * Project home page: http://code.google.com/p/usb-serial-for-android/
*/ */
// IMPORTANT NOTE:
// This source has been modified from the original such that testIfSupported only tests for a vendor id
// match. If that matches it allows all product ids through. This provides for better match on unknown boards.
package com.hoho.android.usbserial.driver; package com.hoho.android.usbserial.driver;
import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDevice;
@ -230,21 +234,7 @@ public enum UsbSerialProber {
* @param supportedDevices map of vendor IDs to product ID(s) * @param supportedDevices map of vendor IDs to product ID(s)
* @return {@code true} if supported * @return {@code true} if supported
*/ */
private static boolean testIfSupported(final UsbDevice usbDevice, private static boolean testIfSupported(final UsbDevice usbDevice, final Map<Integer, int[]> supportedDevices) {
final Map<Integer, int[]> supportedDevices) { return supportedDevices.containsKey(usbDevice.getVendorId());
final int[] supportedProducts = supportedDevices.get(
Integer.valueOf(usbDevice.getVendorId()));
if (supportedProducts == null) {
return false;
}
final int productId = usbDevice.getProductId();
for (int supportedProductId : supportedProducts) {
if (productId == supportedProductId) {
return true;
}
}
return false;
} }
} }

16
android/src/org/qgroundcontrol/qgchelper/UsbDeviceJNI.java

@ -68,6 +68,8 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
private static TextToSpeech m_tts; private static TextToSpeech m_tts;
private static PowerManager.WakeLock m_wl; private static PowerManager.WakeLock m_wl;
public static Context m_context;
private final static UsbIoManager.Listener m_Listener = private final static UsbIoManager.Listener m_Listener =
new UsbIoManager.Listener() new UsbIoManager.Listener()
{ {
@ -90,6 +92,10 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
private static native void nativeDeviceException(int userDataA, String messageA); private static native void nativeDeviceException(int userDataA, String messageA);
private static native void nativeDeviceNewData(int userDataA, byte[] dataA); private static native void nativeDeviceNewData(int userDataA, byte[] dataA);
// Native C++ functions called to log output
public static native void qgcLogDebug(String message);
public static native void qgcLogWarning(String message);
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// //
// Constructor. Only used once to create the initial instance for the static functions. // Constructor. Only used once to create the initial instance for the static functions.
@ -252,7 +258,7 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
tempL = tempL + Integer.toString(deviceL.getVendorId()) + ":"; tempL = tempL + Integer.toString(deviceL.getVendorId()) + ":";
listL[countL] = tempL; listL[countL] = tempL;
countL++; countL++;
//Log.i(TAG, "Found " + tempL); qgcLogDebug("Found " + tempL);
} }
} }
@ -273,11 +279,13 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
// calls like close(), read(), and write(). // calls like close(), read(), and write().
// //
///////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////
public static int open(String nameA, int userDataA) public static int open(Context parentContext, String nameA, int userDataA)
{ {
int idL = BAD_PORT; int idL = BAD_PORT;
Log.i(TAG, "Getting device list"); m_context = parentContext;
//qgcLogDebug("Getting device list");
if (!getCurrentDevices()) if (!getCurrentDevices())
return BAD_PORT; return BAD_PORT;
@ -366,7 +374,7 @@ public class UsbDeviceJNI extends QtActivity implements TextToSpeech.OnInitListe
m_ioManager.remove(idL); m_ioManager.remove(idL);
} }
Log.e(TAG, "Port open exception"); qgcLogWarning("Port open exception: " + exA.getMessage());
return BAD_PORT; return BAD_PORT;
} }
} }

3
deploy/create_linux_appimage.sh

@ -35,7 +35,8 @@ mkdir -p ${APPDIR}
cd ${TMPDIR} cd ${TMPDIR}
wget -c --quiet http://ftp.us.debian.org/debian/pool/main/u/udev/udev_175-7.2_amd64.deb wget -c --quiet http://ftp.us.debian.org/debian/pool/main/u/udev/udev_175-7.2_amd64.deb
wget -c --quiet http://ftp.us.debian.org/debian/pool/main/e/espeak/espeak_1.46.02-2_amd64.deb wget -c --quiet http://ftp.us.debian.org/debian/pool/main/e/espeak/espeak_1.46.02-2_amd64.deb
wget -c --quiet http://ftp.us.debian.org/debian/pool/main/libs/libsdl1.2/libsdl1.2debian_1.2.15-5_amd64.deb wget -c --quiet http://ftp.us.debian.org/debian/pool/main/libs/libsdl2/libsdl2-2.0-0_2.0.2%2bdfsg1-6_amd64.deb
cd ${APPDIR} cd ${APPDIR}
find ../ -name *.deb -exec dpkg -x {} . \; find ../ -name *.deb -exec dpkg -x {} . \;

2
libs/mavlink/include/mavlink/v1.0

@ -1 +1 @@
Subproject commit e93ac62981a338a7c823364e7c4ff1077e3f8fc1 Subproject commit 13a478092fc9c2faa90c553c362e799ba3bad4e8

2
libs/mavlink/include/mavlink/v2.0

@ -1 +1 @@
Subproject commit 36f37bde1df2dd36661fbcbd6ed5aaf0424c8269 Subproject commit 094e765e6353390ac2973023287b7022e696a57e

69
libs/qtandroidserialport/src/qserialport_android.cpp

@ -46,10 +46,10 @@
#include <QtAndroidExtras/QtAndroidExtras> #include <QtAndroidExtras/QtAndroidExtras>
#include <QtAndroidExtras/QAndroidJniObject> #include <QtAndroidExtras/QAndroidJniObject>
#include <android/log.h>
#include "qserialport_android_p.h" #include "qserialport_android_p.h"
QGC_LOGGING_CATEGORY(AndroidSerialPortLog, "AndroidSerialPortLog")
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
#define BAD_PORT 0 #define BAD_PORT 0
@ -91,6 +91,30 @@ static void jniDeviceException(JNIEnv *envA, jobject thizA, jint userDataA, jstr
} }
} }
static void jniLogDebug(JNIEnv *envA, jobject thizA, jstring messageA)
{
Q_UNUSED(thizA);
const char *stringL = envA->GetStringUTFChars(messageA, NULL);
QString logMessage = QString::fromUtf8(stringL);
envA->ReleaseStringUTFChars(messageA, stringL);
if (envA->ExceptionCheck())
envA->ExceptionClear();
qCDebug(AndroidSerialPortLog) << logMessage;
}
static void jniLogWarning(JNIEnv *envA, jobject thizA, jstring messageA)
{
Q_UNUSED(thizA);
const char *stringL = envA->GetStringUTFChars(messageA, NULL);
QString logMessage = QString::fromUtf8(stringL);
envA->ReleaseStringUTFChars(messageA, stringL);
if (envA->ExceptionCheck())
envA->ExceptionClear();
qWarning() << logMessage;
}
void cleanJavaException() void cleanJavaException()
{ {
QAndroidJniEnvironment env; QAndroidJniEnvironment env;
@ -116,13 +140,15 @@ QSerialPortPrivate::QSerialPortPrivate(QSerialPort *q)
void QSerialPortPrivate::setNativeMethods(void) void QSerialPortPrivate::setNativeMethods(void)
{ {
__android_log_print(ANDROID_LOG_INFO, kJTag, "Registering Native Functions"); qCDebug(AndroidSerialPortLog) << "Registering Native Functions";
// REGISTER THE C++ FUNCTION WITH JNI // REGISTER THE C++ FUNCTION WITH JNI
JNINativeMethod javaMethods[] { JNINativeMethod javaMethods[] {
{"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast<void *>(jniDeviceHasDisconnected)}, {"nativeDeviceHasDisconnected", "(I)V", reinterpret_cast<void *>(jniDeviceHasDisconnected)},
{"nativeDeviceNewData", "(I[B)V", reinterpret_cast<void *>(jniDeviceNewData)}, {"nativeDeviceNewData", "(I[B)V", reinterpret_cast<void *>(jniDeviceNewData)},
{"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast<void *>(jniDeviceException)} {"nativeDeviceException", "(ILjava/lang/String;)V", reinterpret_cast<void *>(jniDeviceException)},
{"qgcLogDebug", "(Ljava/lang/String;)V", reinterpret_cast<void *>(jniLogDebug)},
{"qgcLogWarning", "(Ljava/lang/String;)V", reinterpret_cast<void *>(jniLogWarning)}
}; };
QAndroidJniEnvironment jniEnv; QAndroidJniEnvironment jniEnv;
@ -133,36 +159,36 @@ void QSerialPortPrivate::setNativeMethods(void)
jclass objectClass = jniEnv->FindClass(kJniClassName); jclass objectClass = jniEnv->FindClass(kJniClassName);
if(!objectClass) { if(!objectClass) {
__android_log_print(ANDROID_LOG_ERROR, kJTag, "Couldn't find class: %s", kJniClassName); qWarning() << "Couldn't find class:" << kJniClassName;
return; return;
} }
jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0])); jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0]));
__android_log_print(ANDROID_LOG_INFO, kJTag, "Native Functions Registered"); if (val < 0) {
qWarning() << "Error registering methods: " << val;
} else {
qCDebug(AndroidSerialPortLog) << "Native Functions Registered";
}
if (jniEnv->ExceptionCheck()) { if (jniEnv->ExceptionCheck()) {
jniEnv->ExceptionDescribe(); jniEnv->ExceptionDescribe();
jniEnv->ExceptionClear(); jniEnv->ExceptionClear();
} }
if (val < 0) {
__android_log_print(ANDROID_LOG_ERROR, kJTag, "Error registering methods");
}
} }
bool QSerialPortPrivate::open(QIODevice::OpenMode mode) bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
{ {
rwMode = mode; rwMode = mode;
__android_log_print(ANDROID_LOG_INFO, kJTag, "Opening %s", systemLocation.toLatin1().data()); qCDebug(AndroidSerialPortLog) << "Opening" << systemLocation.toLatin1().data();
__android_log_print(ANDROID_LOG_INFO, kJTag, "Calling Java Open");
QAndroidJniObject jnameL = QAndroidJniObject::fromString(systemLocation); QAndroidJniObject jnameL = QAndroidJniObject::fromString(systemLocation);
cleanJavaException(); cleanJavaException();
deviceId = QAndroidJniObject::callStaticMethod<jint>( deviceId = QAndroidJniObject::callStaticMethod<jint>(
kJniClassName, kJniClassName,
"open", "open",
"(Ljava/lang/String;I)I", "(Landroid/content/Context;Ljava/lang/String;I)I",
QtAndroid::androidActivity().object(),
jnameL.object<jstring>(), jnameL.object<jstring>(),
(jint)this); (jint)this);
cleanJavaException(); cleanJavaException();
@ -171,20 +197,11 @@ bool QSerialPortPrivate::open(QIODevice::OpenMode mode)
if (deviceId == BAD_PORT) if (deviceId == BAD_PORT)
{ {
__android_log_print(ANDROID_LOG_ERROR, kJTag, "Error opening %s", systemLocation.toLatin1().data()); qWarning() << "Error opening %s" << systemLocation.toLatin1().data();
q_ptr->setError(QSerialPort::DeviceNotFoundError); q_ptr->setError(QSerialPort::DeviceNotFoundError);
return false; return false;
} }
__android_log_print(ANDROID_LOG_INFO, kJTag, "Calling Java getDeviceHandle");
cleanJavaException();
descriptor = QAndroidJniObject::callStaticMethod<jint>(
kJniClassName,
"getDeviceHandle",
"(I)I",
deviceId);
cleanJavaException();
if (rwMode == QIODevice::WriteOnly) if (rwMode == QIODevice::WriteOnly)
stopReadThread(); stopReadThread();
@ -196,7 +213,7 @@ void QSerialPortPrivate::close()
if (deviceId == BAD_PORT) if (deviceId == BAD_PORT)
return; return;
__android_log_print(ANDROID_LOG_INFO, kJTag, "Closing %s", systemLocation.toLatin1().data()); qCDebug(AndroidSerialPortLog) << "Closing" << systemLocation.toLatin1().data();
cleanJavaException(); cleanJavaException();
jboolean resultL = QAndroidJniObject::callStaticMethod<jboolean>( jboolean resultL = QAndroidJniObject::callStaticMethod<jboolean>(
kJniClassName, kJniClassName,

3
libs/qtandroidserialport/src/qserialport_android_p.h

@ -49,6 +49,9 @@
#include <QtCore/qstringlist.h> #include <QtCore/qstringlist.h>
#include <QtCore/qthread.h> #include <QtCore/qthread.h>
#include "QGCLoggingCategory.h"
Q_DECLARE_LOGGING_CATEGORY(AndroidSerialPortLog)
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

5
src/AutoPilotPlugins/PX4/AirframeComponent.qml

@ -104,8 +104,9 @@ SetupPage {
QGCLabel { QGCLabel {
anchors.fill: parent anchors.fill: parent
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: qsTr("Clicking “Apply” will save the changes you have made to your airframe configuration. ") + text: qsTr("Clicking Apply will save the changes you have made to your airframe configuration.<br><br>\
qsTr("Your vehicle will also be restarted in order to complete the process.") All vehicle parameters other than Radio Calibration will be reset.<br><br>\
Your vehicle will also be restarted in order to complete the process.")
} }
} }
} }

183
src/AutoPilotPlugins/PX4/AirframeFactMetaData.xml

@ -14,10 +14,10 @@
</airframe> </airframe>
</airframe_group> </airframe_group>
<airframe_group image="FlyingWing" name="Flying Wing"> <airframe_group image="FlyingWing" name="Flying Wing">
<airframe id="3030" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="IO Camflyer"> <airframe id="3036" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="Sparkle Tech Pigeon">
<maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer> <maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer>
<type>Flying Wing</type> <type>Flying Wing</type>
<url>https://pixhawk.org/platforms/planes/bormatec_camflyer_q</url> <url>http://www.sparkletech.hk/</url>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
@ -47,10 +47,14 @@
<output name="MAIN2">right aileron</output> <output name="MAIN2">right aileron</output>
<output name="MAIN4">throttle</output> <output name="MAIN4">throttle</output>
</airframe> </airframe>
<airframe id="3033" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Wing Wing (aka Z-84) Flying Wing"> <airframe id="3034" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="FX-79 Buffalo Flying Wing">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer>
<type>Flying Wing</type> <type>Flying Wing</type>
<url>https://pixhawk.org/platforms/planes/z-84_wing_wing</url> </airframe>
<airframe id="3030" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="IO Camflyer">
<maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer>
<type>Flying Wing</type>
<url>https://pixhawk.org/platforms/planes/bormatec_camflyer_q</url>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
@ -58,18 +62,14 @@
<output name="MAIN2">right aileron</output> <output name="MAIN2">right aileron</output>
<output name="MAIN4">throttle</output> <output name="MAIN4">throttle</output>
</airframe> </airframe>
<airframe id="3034" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="FX-79 Buffalo Flying Wing">
<maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer>
<type>Flying Wing</type>
</airframe>
<airframe id="3035" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="Viper"> <airframe id="3035" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="Viper">
<maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer> <maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer>
<type>Flying Wing</type> <type>Flying Wing</type>
</airframe> </airframe>
<airframe id="3036" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="Sparkle Tech Pigeon"> <airframe id="3033" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Wing Wing (aka Z-84) Flying Wing">
<maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Flying Wing</type> <type>Flying Wing</type>
<url>http://www.sparkletech.hk/</url> <url>https://pixhawk.org/platforms/planes/z-84_wing_wing</url>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
@ -82,6 +82,12 @@
<type>Flying Wing</type> <type>Flying Wing</type>
</airframe> </airframe>
</airframe_group> </airframe_group>
<airframe_group image="Helicopter" name="Helicopter">
<airframe id="16001" maintainer="Bart Slinger &lt;bartslinger@gmail.com&gt;" name="Blade 130X">
<maintainer>Bart Slinger &lt;bartslinger@gmail.com&gt;</maintainer>
<type>Helicopter</type>
</airframe>
</airframe_group>
<airframe_group image="HexaRotorPlus" name="Hexarotor +"> <airframe_group image="HexaRotorPlus" name="Hexarotor +">
<airframe id="7001" maintainer="Anton Babushkin &lt;anton@px4.io&gt;" name="Generic Hexarotor + geometry"> <airframe id="7001" maintainer="Anton Babushkin &lt;anton@px4.io&gt;" name="Generic Hexarotor + geometry">
<maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer> <maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer>
@ -177,16 +183,12 @@
<maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer> <maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer>
<type>Quadrotor Wide</type> <type>Quadrotor Wide</type>
</airframe> </airframe>
<airframe id="10017" maintainer="Thomas Gubler &lt;thomas@px4.io&gt;" name="Steadidrone QU4D">
<maintainer>Thomas Gubler &lt;thomas@px4.io&gt;</maintainer>
<type>Quadrotor Wide</type>
</airframe>
<airframe id="10018" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="Team Blacksheep Discovery Endurance"> <airframe id="10018" maintainer="Simon Wilks &lt;simon@px4.io&gt;" name="Team Blacksheep Discovery Endurance">
<maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer> <maintainer>Simon Wilks &lt;simon@px4.io&gt;</maintainer>
<type>Quadrotor Wide</type> <type>Quadrotor Wide</type>
</airframe> </airframe>
<airframe id="10019" maintainer="Anton Matosov &lt;anton.matosov@gmail.com&gt;" name="HobbyKing SK450 DeadCat modification"> <airframe id="10017" maintainer="Thomas Gubler &lt;thomas@px4.io&gt;" name="Steadidrone QU4D">
<maintainer>Anton Matosov &lt;anton.matosov@gmail.com&gt;</maintainer> <maintainer>Thomas Gubler &lt;thomas@px4.io&gt;</maintainer>
<type>Quadrotor Wide</type> <type>Quadrotor Wide</type>
</airframe> </airframe>
</airframe_group> </airframe_group>
@ -195,75 +197,90 @@
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
</airframe> </airframe>
<airframe id="4001" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Generic Quadrotor X config"> <airframe id="4011" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="DJI Flame Wheel F450">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
</airframe> </airframe>
<airframe id="4002" maintainer="James Goppert &lt;james.goppert@gmail.com&gt;" name="Lumenier QAV-R (raceblade) 5&quot; arms"> <airframe id="4012" maintainer="Pavel Kirienko &lt;pavel@px4.io&gt;" name="F450-sized quadrotor with CAN">
<maintainer>James Goppert &lt;james.goppert@gmail.com&gt;</maintainer> <maintainer>Pavel Kirienko &lt;pavel@px4.io&gt;</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="10021" maintainer="Leon Mueller &lt;thedevleon&gt;" name="H4 680mm with Z1 Tiny2 Gimbal">
<maintainer>Leon Mueller &lt;thedevleon&gt;</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4010" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="DJI Flame Wheel F330">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
</airframe> </airframe>
<airframe id="4008" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="AR.Drone Frame"> <airframe id="4040" maintainer="Blankered" name="Reaper 500 Quad">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Blankered</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
</airframe> </airframe>
<airframe id="4009" maintainer="Mark Whitehorn &lt;kd0aij@gmail.com&gt;" name="Lumenier QAV250"> <airframe id="4001" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Generic Quadrotor X config">
<maintainer>Mark Whitehorn &lt;kd0aij@gmail.com&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
</airframe> </airframe>
<airframe id="4010" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="DJI Flame Wheel F330"> <airframe id="4050" maintainer="Mark Whitehorn &lt;kd0aij@gmail.com&gt;" name="Generic 250 Racer">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Mark Whitehorn &lt;kd0aij@gmail.com&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
</airframe> </airframe>
<airframe id="4011" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="DJI Flame Wheel F450"> <airframe id="4060" maintainer="James Goppert &lt;james.goppert@gmail.com&gt;" name="DJI Matrice 100">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>James Goppert &lt;james.goppert@gmail.com&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
</airframe> </airframe>
<airframe id="4012" maintainer="Pavel Kirienko &lt;pavel@px4.io&gt;" name="F450-sized quadrotor with CAN"> <airframe id="4008" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="AR.Drone Frame">
<maintainer>Pavel Kirienko &lt;pavel@px4.io&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
</airframe> </airframe>
<airframe id="4020" maintainer="Thomas Gubler &lt;thomas@px4.io&gt;" name="Hobbyking Micro PCB"> <airframe id="4020" maintainer="Thomas Gubler &lt;thomas@px4.io&gt;" name="Hobbyking Micro PCB">
<maintainer>Thomas Gubler &lt;thomas@px4.io&gt;</maintainer> <maintainer>Thomas Gubler &lt;thomas@px4.io&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
</airframe> </airframe>
<airframe id="4030" maintainer="Andreas Antener &lt;andreas@uaventure.com&gt;" name="3DR Solo"> <airframe id="4009" maintainer="Mark Whitehorn &lt;kd0aij@gmail.com&gt;" name="Lumenier QAV250">
<maintainer>Andreas Antener &lt;andreas@uaventure.com&gt;</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4040" maintainer="Blankered" name="Reaper 500 Quad">
<maintainer>Blankered</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4050" maintainer="Mark Whitehorn &lt;kd0aij@gmail.com&gt;" name="Generic 250 Racer">
<maintainer>Mark Whitehorn &lt;kd0aij@gmail.com&gt;</maintainer> <maintainer>Mark Whitehorn &lt;kd0aij@gmail.com&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
</airframe> </airframe>
<airframe id="4060" maintainer="James Goppert &lt;james.goppert@gmail.com&gt;" name="DJI Matrice 100"> <airframe id="4002" maintainer="James Goppert &lt;james.goppert@gmail.com&gt;" name="Lumenier QAV-R (raceblade) 5&quot; arms">
<maintainer>James Goppert &lt;james.goppert@gmail.com&gt;</maintainer> <maintainer>James Goppert &lt;james.goppert@gmail.com&gt;</maintainer>
<type>Quadrotor x</type> <type>Quadrotor x</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output> <output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output> <output name="AUX3">feed-through of RC AUX3 channel</output>
</airframe> </airframe>
<airframe id="4900" maintainer="John Doe &lt;john@example.com&gt;" name="Crazyflie 2.0">
<type>Quadrotor x</type>
</airframe>
<airframe id="4013" maintainer="Michael Schaeuble" name="Parrot Bebop Frame">
<maintainer>Michael Schaeuble</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4002" maintainer="Leon Mueller &lt;thedevleon&gt;" name="Generic Quadrotor X config with mount (e.g. gimbal)">
<maintainer>Leon Mueller &lt;thedevleon&gt;</maintainer>
<type>Quadrotor x</type>
</airframe>
<airframe id="4030" maintainer="Andreas Antener &lt;andreas@uaventure.com&gt;" name="3DR Solo">
<maintainer>Andreas Antener &lt;andreas@uaventure.com&gt;</maintainer>
<type>Quadrotor x</type>
</airframe>
</airframe_group> </airframe_group>
<airframe_group image="Rover" name="Rover"> <airframe_group image="Rover" name="Rover">
<airframe id="50001" maintainer="John Doe &lt;john@example.com&gt;" name="Axial Racing AX10"> <airframe id="50001" maintainer="John Doe &lt;john@example.com&gt;" name="Axial Racing AX10">
@ -271,6 +288,10 @@
</airframe> </airframe>
</airframe_group> </airframe_group>
<airframe_group image="AirframeSimulation" name="Simulation"> <airframe_group image="AirframeSimulation" name="Simulation">
<airframe id="1001" maintainer="Anton Babushkin &lt;anton@px4.io&gt;" name="HIL Quadcopter X">
<maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer>
<type>Simulation</type>
</airframe>
<airframe id="1000" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="HILStar (XPlane)"> <airframe id="1000" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="HILStar (XPlane)">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Simulation</type> <type>Simulation</type>
@ -279,28 +300,12 @@
<output name="MAIN3">rudder</output> <output name="MAIN3">rudder</output>
<output name="MAIN4">throttle</output> <output name="MAIN4">throttle</output>
</airframe> </airframe>
<airframe id="1001" maintainer="Anton Babushkin &lt;anton@px4.io&gt;" name="HIL Quadcopter X">
<maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer>
<type>Simulation</type>
</airframe>
<airframe id="1003" maintainer="Anton Babushkin &lt;anton@px4.io&gt;" name="HIL Quadcopter +"> <airframe id="1003" maintainer="Anton Babushkin &lt;anton@px4.io&gt;" name="HIL Quadcopter +">
<maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer> <maintainer>Anton Babushkin &lt;anton@px4.io&gt;</maintainer>
<type>Simulation</type> <type>Simulation</type>
</airframe> </airframe>
<airframe id="1004" maintainer="Thomas Gubler &lt;thomas@px4.io&gt;" name="HIL Rascal 110 (Flightgear)">
<maintainer>Thomas Gubler &lt;thomas@px4.io&gt;</maintainer>
<type>Simulation</type>
</airframe>
<airframe id="1005" maintainer="Thomas Gubler &lt;thomas@px4.io&gt;" name="HIL Malolo 1 (Flightgear)">
<maintainer>Thomas Gubler &lt;thomas@px4.io&gt;</maintainer>
<type>Simulation</type>
</airframe>
</airframe_group> </airframe_group>
<airframe_group image="Plane" name="Standard Plane"> <airframe_group image="Plane" name="Standard Plane">
<airframe id="2100" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Multiplex Easystar">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Standard Plane</type>
</airframe>
<airframe id="2101" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Standard AERT Plane"> <airframe id="2101" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Standard AERT Plane">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Standard Plane</type> <type>Standard Plane</type>
@ -313,7 +318,25 @@
<output name="MAIN4">throttle</output> <output name="MAIN4">throttle</output>
<output name="MAIN5">flaps</output> <output name="MAIN5">flaps</output>
</airframe> </airframe>
<airframe id="2102" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Skywalker (3DR Aero)"> <airframe id="2105" maintainer="Andreas Antener &lt;andreas@uaventure.com&gt;" name="Bormatec Maja">
<maintainer>Andreas Antener &lt;andreas@uaventure.com&gt;</maintainer>
<type>Standard Plane</type>
<output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output>
<output name="MAIN1">aileron</output>
<output name="MAIN2">aileron</output>
<output name="MAIN3">elevator</output>
<output name="MAIN4">rudder</output>
<output name="MAIN5">throttle</output>
<output name="MAIN6">wheel</output>
<output name="MAIN7">flaps</output>
</airframe>
<airframe id="2100" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Multiplex Easystar">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Standard Plane</type>
</airframe>
<airframe id="2104" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Standard AETR Plane">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Standard Plane</type> <type>Standard Plane</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
@ -335,7 +358,7 @@
<output name="MAIN2">elevator</output> <output name="MAIN2">elevator</output>
<output name="MAIN4">throttle</output> <output name="MAIN4">throttle</output>
</airframe> </airframe>
<airframe id="2104" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Standard AETR Plane"> <airframe id="2102" maintainer="Lorenz Meier &lt;lorenz@px4.io&gt;" name="Skywalker (3DR Aero)">
<maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer> <maintainer>Lorenz Meier &lt;lorenz@px4.io&gt;</maintainer>
<type>Standard Plane</type> <type>Standard Plane</type>
<output name="AUX1">feed-through of RC AUX1 channel</output> <output name="AUX1">feed-through of RC AUX1 channel</output>
@ -347,30 +370,8 @@
<output name="MAIN4">rudder</output> <output name="MAIN4">rudder</output>
<output name="MAIN5">flaps</output> <output name="MAIN5">flaps</output>
</airframe> </airframe>
<airframe id="2105" maintainer="Andreas Antener &lt;andreas@uaventure.com&gt;" name="Bormatec Maja">
<maintainer>Andreas Antener &lt;andreas@uaventure.com&gt;</maintainer>
<type>Standard Plane</type>
<output name="AUX1">feed-through of RC AUX1 channel</output>
<output name="AUX2">feed-through of RC AUX2 channel</output>
<output name="AUX3">feed-through of RC AUX3 channel</output>
<output name="MAIN1">aileron</output>
<output name="MAIN2">aileron</output>
<output name="MAIN3">elevator</output>
<output name="MAIN4">rudder</output>
<output name="MAIN5">throttle</output>
<output name="MAIN6">wheel</output>
<output name="MAIN7">flaps</output>
</airframe>
</airframe_group> </airframe_group>
<airframe_group image="VTOLPlane" name="Standard VTOL"> <airframe_group image="VTOLPlane" name="Standard VTOL">
<airframe id="13005" maintainer="Simon Wilks &lt;simon@uaventure.com&gt;" name="Fun Cub Quad VTOL.">
<maintainer>Simon Wilks &lt;simon@uaventure.com&gt;</maintainer>
<type>Standard VTOL</type>
</airframe>
<airframe id="13006" maintainer="Simon Wilks &lt;simon@uaventure.com&gt;" name="Generic quad delta VTOL.">
<maintainer>Simon Wilks &lt;simon@uaventure.com&gt;</maintainer>
<type>Standard VTOL</type>
</airframe>
<airframe id="13007" maintainer="Sander Smeets &lt;sander@droneslab.com&gt;" name="Generic AAVVT v-tail plane airframe with Quad VTOL."> <airframe id="13007" maintainer="Sander Smeets &lt;sander@droneslab.com&gt;" name="Generic AAVVT v-tail plane airframe with Quad VTOL.">
<maintainer>Sander Smeets &lt;sander@droneslab.com&gt;</maintainer> <maintainer>Sander Smeets &lt;sander@droneslab.com&gt;</maintainer>
<type>Standard VTOL</type> <type>Standard VTOL</type>
@ -379,6 +380,14 @@
<maintainer>Sander Smeets &lt;sander@droneslab.com&gt;</maintainer> <maintainer>Sander Smeets &lt;sander@droneslab.com&gt;</maintainer>
<type>Standard VTOL</type> <type>Standard VTOL</type>
</airframe> </airframe>
<airframe id="13006" maintainer="Simon Wilks &lt;simon@uaventure.com&gt;" name="Generic quad delta VTOL.">
<maintainer>Simon Wilks &lt;simon@uaventure.com&gt;</maintainer>
<type>Standard VTOL</type>
</airframe>
<airframe id="13005" maintainer="Simon Wilks &lt;simon@uaventure.com&gt;" name="Fun Cub Quad VTOL.">
<maintainer>Simon Wilks &lt;simon@uaventure.com&gt;</maintainer>
<type>Standard VTOL</type>
</airframe>
<airframe id="13009" maintainer="Andreas Antener &lt;andreas@uaventure.com&gt;" name="Sparkle Tech Ranger VTOL"> <airframe id="13009" maintainer="Andreas Antener &lt;andreas@uaventure.com&gt;" name="Sparkle Tech Ranger VTOL">
<maintainer>Andreas Antener &lt;andreas@uaventure.com&gt;</maintainer> <maintainer>Andreas Antener &lt;andreas@uaventure.com&gt;</maintainer>
<type>Standard VTOL</type> <type>Standard VTOL</type>
@ -407,24 +416,24 @@
</airframe> </airframe>
</airframe_group> </airframe_group>
<airframe_group image="VTOLQuadRotorTailSitter" name="VTOL Quad Tailsitter"> <airframe_group image="VTOLQuadRotorTailSitter" name="VTOL Quad Tailsitter">
<airframe id="13003" maintainer="Roman Bapst &lt;roman@px4.io&gt;" name="Quadrotor X Tailsitter"> <airframe id="13004" maintainer="Roman Bapst &lt;roman@px4.io&gt;" name="Quadrotor + Tailsitter">
<maintainer>Roman Bapst &lt;roman@px4.io&gt;</maintainer> <maintainer>Roman Bapst &lt;roman@px4.io&gt;</maintainer>
<type>VTOL Quad Tailsitter</type> <type>VTOL Quad Tailsitter</type>
</airframe> </airframe>
<airframe id="13004" maintainer="Roman Bapst &lt;roman@px4.io&gt;" name="Quadrotor + Tailsitter"> <airframe id="13003" maintainer="Roman Bapst &lt;roman@px4.io&gt;" name="Quadrotor X Tailsitter">
<maintainer>Roman Bapst &lt;roman@px4.io&gt;</maintainer> <maintainer>Roman Bapst &lt;roman@px4.io&gt;</maintainer>
<type>VTOL Quad Tailsitter</type> <type>VTOL Quad Tailsitter</type>
</airframe> </airframe>
</airframe_group> </airframe_group>
<airframe_group image="VTOLTiltRotor" name="VTOL Tiltrotor"> <airframe_group image="VTOLTiltRotor" name="VTOL Tiltrotor">
<airframe id="13002" maintainer="Roman Bapst &lt;roman@px4.io&gt;" name="BirdsEyeView Aerobotics FireFly6">
<maintainer>Roman Bapst &lt;roman@px4.io&gt;</maintainer>
<type>VTOL Tiltrotor</type>
</airframe>
<airframe id="13010" maintainer="Samay Siga &lt;samay_s@icloud.com&gt;" name="CruiseAder Claire"> <airframe id="13010" maintainer="Samay Siga &lt;samay_s@icloud.com&gt;" name="CruiseAder Claire">
<maintainer>Samay Siga &lt;samay_s@icloud.com&gt;</maintainer> <maintainer>Samay Siga &lt;samay_s@icloud.com&gt;</maintainer>
<type>VTOL Tiltrotor</type> <type>VTOL Tiltrotor</type>
</airframe> </airframe>
<airframe id="13002" maintainer="Roman Bapst &lt;roman@px4.io&gt;" name="BirdsEyeView Aerobotics FireFly6">
<maintainer>Roman Bapst &lt;roman@px4.io&gt;</maintainer>
<type>VTOL Tiltrotor</type>
</airframe>
</airframe_group> </airframe_group>
<airframe_group image="AirframeUnknown" name="custom"> <airframe_group image="AirframeUnknown" name="custom">
<airframe id="20000" maintainer="Julian Oes &lt;julian@oes.ch&gt;&#10;This startup can be used on Pixhawk/Pixfalcon/Pixracer for the&#10;passthrough of RC input and PWM output." name="Passthrough mode for Snapdragon"> <airframe id="20000" maintainer="Julian Oes &lt;julian@oes.ch&gt;&#10;This startup can be used on Pixhawk/Pixfalcon/Pixracer for the&#10;passthrough of RC input and PWM output." name="Passthrough mode for Snapdragon">

1296
src/FirmwarePlugin/PX4/PX4ParameterFactMetaData.xml

File diff suppressed because it is too large Load Diff

30
src/FlightMap/FlightMap.qml

@ -197,7 +197,8 @@ Map {
property alias drawingPolygon: polygonDrawer.hoverEnabled property alias drawingPolygon: polygonDrawer.hoverEnabled
property bool adjustingPolygon: false property bool adjustingPolygon: false
property bool polygonReady: polygonDrawerPolygon.path.length > 3 ///< true: enough points have been captured to create a closed polygon property bool polygonReady: polygonDrawerPolygonSet.path.length > 2 ///< true: enough points have been captured to create a closed polygon
property bool justClicked: false
property var _callbackObject property var _callbackObject
@ -220,8 +221,7 @@ Map {
return false return false
} }
var polygonPath = polygonDrawerPolygon.path var polygonPath = polygonDrawerPolygonSet.path
polygonPath.pop() // get rid of drag coordinate
_cancelCapturePolygon() _cancelCapturePolygon()
polygonDrawer._callbackObject.polygonCaptureFinished(polygonPath) polygonDrawer._callbackObject.polygonCaptureFinished(polygonPath)
return true return true
@ -322,10 +322,13 @@ Map {
polygonDrawerNextPoint.path = [ bogusCoord, bogusCoord ] polygonDrawerNextPoint.path = [ bogusCoord, bogusCoord ]
polygonDrawerPolygon.path = [ ] polygonDrawerPolygon.path = [ ]
polygonDrawerNextPoint.path = [ ] polygonDrawerNextPoint.path = [ ]
polygonDrawerPolygonSet.path = [ bogusCoord, bogusCoord ]
polygonDrawerPolygonSet.path = [ ]
} }
onClicked: { onClicked: {
if (mouse.button == Qt.LeftButton) { if (mouse.button == Qt.LeftButton) {
polygonDrawer.justClicked = true
if (polygonDrawerPolygon.path.length > 2) { if (polygonDrawerPolygon.path.length > 2) {
// Make sure the new line doesn't intersect the existing polygon // Make sure the new line doesn't intersect the existing polygon
var lastSegment = polygonDrawerPolygon.path.length - 2 var lastSegment = polygonDrawerPolygon.path.length - 2
@ -349,8 +352,7 @@ Map {
// Update finalized coordinate // Update finalized coordinate
polygonPath[polygonDrawerPolygon.path.length - 1] = clickCoordinate polygonPath[polygonDrawerPolygon.path.length - 1] = clickCoordinate
} }
// Add next drag coordinate polygonDrawerPolygonSet.path = polygonPath
polygonPath.push(clickCoordinate)
polygonDrawerPolygon.path = polygonPath polygonDrawerPolygon.path = polygonPath
} else if (polygonDrawer.polygonReady) { } else if (polygonDrawer.polygonReady) {
finishCapturePolygon() finishCapturePolygon()
@ -360,14 +362,18 @@ Map {
onPositionChanged: { onPositionChanged: {
if (polygonDrawerPolygon.path.length) { if (polygonDrawerPolygon.path.length) {
var dragCoordinate = _map.toCoordinate(Qt.point(mouse.x, mouse.y)) var dragCoordinate = _map.toCoordinate(Qt.point(mouse.x, mouse.y))
var polygonPath = polygonDrawerPolygon.path
if (polygonDrawer.justClicked){
polygonPath.push(dragCoordinate)
polygonDrawer.justClicked = false
}
// Update drag line // Update drag line
polygonDrawerNextPoint.path = [ polygonDrawerPolygon.path[polygonDrawerPolygon.path.length - 2], dragCoordinate ] polygonDrawerNextPoint.path = [ polygonDrawerPolygon.path[polygonDrawerPolygon.path.length - 2], dragCoordinate ]
// Update drag coordinate
var polygonPath = polygonDrawerPolygon.path
polygonPath[polygonDrawerPolygon.path.length - 1] = dragCoordinate polygonPath[polygonDrawerPolygon.path.length - 1] = dragCoordinate
polygonDrawerPolygon.path = polygonPath polygonDrawerPolygon.path = polygonPath
} }
} }
} }
@ -377,14 +383,20 @@ Map {
id: polygonDrawerPolygon id: polygonDrawerPolygon
color: "blue" color: "blue"
opacity: 0.5 opacity: 0.5
visible: polygonDrawer.drawingPolygon visible: polygonDrawerPolygon.path.length > 2
}
MapPolygon {
id: polygonDrawerPolygonSet
color: 'green'
opacity: 0.5
visible: polygonDrawer.polygonReady
} }
/// Next line for polygon /// Next line for polygon
MapPolyline { MapPolyline {
id: polygonDrawerNextPoint id: polygonDrawerNextPoint
line.color: "green" line.color: "green"
line.width: 5 line.width: 3
visible: polygonDrawer.drawingPolygon visible: polygonDrawer.drawingPolygon
} }

86
src/Joystick/Joystick.cc

@ -23,6 +23,8 @@ const char* Joystick::_calibratedSettingsKey = "Calibrated1"; // Increment
const char* Joystick::_buttonActionSettingsKey = "ButtonActionName%1"; const char* Joystick::_buttonActionSettingsKey = "ButtonActionName%1";
const char* Joystick::_throttleModeSettingsKey = "ThrottleMode"; const char* Joystick::_throttleModeSettingsKey = "ThrottleMode";
const char* Joystick::_exponentialSettingsKey = "Exponential"; const char* Joystick::_exponentialSettingsKey = "Exponential";
const char* Joystick::_accumulatorSettingsKey = "Accumulator";
const char* Joystick::_deadbandSettingsKey = "Deadband";
const char* Joystick::_rgFunctionSettingsKey[Joystick::maxFunction] = { const char* Joystick::_rgFunctionSettingsKey[Joystick::maxFunction] = {
"RollAxis", "RollAxis",
@ -46,6 +48,8 @@ Joystick::Joystick(const QString& name, int axisCount, int buttonCount, int hatC
, _lastButtonBits(0) , _lastButtonBits(0)
, _throttleMode(ThrottleModeCenterZero) , _throttleMode(ThrottleModeCenterZero)
, _exponential(false) , _exponential(false)
, _accumulator(false)
, _deadband(false)
, _activeVehicle(NULL) , _activeVehicle(NULL)
, _pollingStartedForCalibration(false) , _pollingStartedForCalibration(false)
, _multiVehicleManager(multiVehicleManager) , _multiVehicleManager(multiVehicleManager)
@ -86,16 +90,19 @@ void Joystick::_loadSettings(void)
_calibrated = settings.value(_calibratedSettingsKey, false).toBool(); _calibrated = settings.value(_calibratedSettingsKey, false).toBool();
_exponential = settings.value(_exponentialSettingsKey, false).toBool(); _exponential = settings.value(_exponentialSettingsKey, false).toBool();
_accumulator = settings.value(_accumulatorSettingsKey, false).toBool();
_deadband = settings.value(_deadbandSettingsKey, false).toBool();
_throttleMode = (ThrottleMode_t)settings.value(_throttleModeSettingsKey, ThrottleModeCenterZero).toInt(&convertOk); _throttleMode = (ThrottleMode_t)settings.value(_throttleModeSettingsKey, ThrottleModeCenterZero).toInt(&convertOk);
badSettings |= !convertOk; badSettings |= !convertOk;
qCDebug(JoystickLog) << "_loadSettings calibrated:throttlemode:exponential:badsettings" << _calibrated << _throttleMode << _exponential << badSettings; qCDebug(JoystickLog) << "_loadSettings calibrated:throttlemode:exponential:deadband:badsettings" << _calibrated << _throttleMode << _exponential << _deadband << badSettings;
QString minTpl ("Axis%1Min"); QString minTpl ("Axis%1Min");
QString maxTpl ("Axis%1Max"); QString maxTpl ("Axis%1Max");
QString trimTpl ("Axis%1Trim"); QString trimTpl ("Axis%1Trim");
QString revTpl ("Axis%1Rev"); QString revTpl ("Axis%1Rev");
QString deadbndTpl ("Axis%1Deadbnd");
for (int axis=0; axis<_axisCount; axis++) { for (int axis=0; axis<_axisCount; axis++) {
Calibration_t* calibration = &_rgCalibration[axis]; Calibration_t* calibration = &_rgCalibration[axis];
@ -109,9 +116,13 @@ void Joystick::_loadSettings(void)
calibration->max = settings.value(maxTpl.arg(axis), 32767).toInt(&convertOk); calibration->max = settings.value(maxTpl.arg(axis), 32767).toInt(&convertOk);
badSettings |= !convertOk; badSettings |= !convertOk;
calibration->deadband = settings.value(deadbndTpl.arg(axis), 0).toInt(&convertOk);
badSettings |= !convertOk;
calibration->reversed = settings.value(revTpl.arg(axis), false).toBool(); calibration->reversed = settings.value(revTpl.arg(axis), false).toBool();
qCDebug(JoystickLog) << "_loadSettings axis:min:max:trim:reversed:badsettings" << axis << calibration->min << calibration->max << calibration->center << calibration->reversed << badSettings;
qCDebug(JoystickLog) << "_loadSettings axis:min:max:trim:reversed:deadband:badsettings" << axis << calibration->min << calibration->max << calibration->center << calibration->reversed << calibration->deadband << badSettings;
} }
for (int function=0; function<maxFunction; function++) { for (int function=0; function<maxFunction; function++) {
@ -145,14 +156,17 @@ void Joystick::_saveSettings(void)
settings.setValue(_calibratedSettingsKey, _calibrated); settings.setValue(_calibratedSettingsKey, _calibrated);
settings.setValue(_exponentialSettingsKey, _exponential); settings.setValue(_exponentialSettingsKey, _exponential);
settings.setValue(_accumulatorSettingsKey, _accumulator);
settings.setValue(_deadbandSettingsKey, _deadband);
settings.setValue(_throttleModeSettingsKey, _throttleMode); settings.setValue(_throttleModeSettingsKey, _throttleMode);
qCDebug(JoystickLog) << "_saveSettings calibrated:throttlemode" << _calibrated << _throttleMode; qCDebug(JoystickLog) << "_saveSettings calibrated:throttlemode:deadband" << _calibrated << _throttleMode << _deadband;
QString minTpl ("Axis%1Min"); QString minTpl ("Axis%1Min");
QString maxTpl ("Axis%1Max"); QString maxTpl ("Axis%1Max");
QString trimTpl ("Axis%1Trim"); QString trimTpl ("Axis%1Trim");
QString revTpl ("Axis%1Rev"); QString revTpl ("Axis%1Rev");
QString deadbndTpl ("Axis%1Deadbnd");
for (int axis=0; axis<_axisCount; axis++) { for (int axis=0; axis<_axisCount; axis++) {
Calibration_t* calibration = &_rgCalibration[axis]; Calibration_t* calibration = &_rgCalibration[axis];
@ -161,14 +175,16 @@ void Joystick::_saveSettings(void)
settings.setValue(minTpl.arg(axis), calibration->min); settings.setValue(minTpl.arg(axis), calibration->min);
settings.setValue(maxTpl.arg(axis), calibration->max); settings.setValue(maxTpl.arg(axis), calibration->max);
settings.setValue(revTpl.arg(axis), calibration->reversed); settings.setValue(revTpl.arg(axis), calibration->reversed);
settings.setValue(deadbndTpl.arg(axis), calibration->deadband);
qCDebug(JoystickLog) << "_saveSettings name:axis:min:max:trim:reversed" qCDebug(JoystickLog) << "_saveSettings name:axis:min:max:trim:reversed:deadband"
<< _name << _name
<< axis << axis
<< calibration->min << calibration->min
<< calibration->max << calibration->max
<< calibration->center << calibration->center
<< calibration->reversed; << calibration->reversed
<< calibration->deadband;
} }
for (int function=0; function<maxFunction; function++) { for (int function=0; function<maxFunction; function++) {
@ -183,7 +199,7 @@ void Joystick::_saveSettings(void)
} }
/// Adjust the raw axis value to the -1:1 range given calibration information /// Adjust the raw axis value to the -1:1 range given calibration information
float Joystick::_adjustRange(int value, Calibration_t calibration) float Joystick::_adjustRange(int value, Calibration_t calibration, bool withDeadbands)
{ {
float valueNormalized; float valueNormalized;
float axisLength; float axisLength;
@ -199,6 +215,12 @@ float Joystick::_adjustRange(int value, Calibration_t calibration)
axisLength = calibration.center - calibration.min; axisLength = calibration.center - calibration.min;
} }
if (withDeadbands) {
if (valueNormalized>calibration.deadband) valueNormalized-=calibration.deadband;
else if (valueNormalized<-calibration.deadband) valueNormalized+=calibration.deadband;
else valueNormalized = 0.f;
}
float axisPercent = valueNormalized / axisLength; float axisPercent = valueNormalized / axisLength;
float correctedValue = axisBasis * axisPercent; float correctedValue = axisBasis * axisPercent;
@ -208,13 +230,14 @@ float Joystick::_adjustRange(int value, Calibration_t calibration)
} }
#if 0 #if 0
qCDebug(JoystickLog) << "_adjustRange corrected:value:min:max:center:reversed:basis:normalized:length" qCDebug(JoystickLog) << "_adjustRange corrected:value:min:max:center:reversed:deadband:basis:normalized:length"
<< correctedValue << correctedValue
<< value << value
<< calibration.min << calibration.min
<< calibration.max << calibration.max
<< calibration.center << calibration.center
<< calibration.center << calibration.reversed
<< calibration.deadband
<< axisBasis << axisBasis
<< valueNormalized << valueNormalized
<< axisLength; << axisLength;
@ -265,16 +288,25 @@ void Joystick::run(void)
if (_calibrationMode != CalibrationModeCalibrating) { if (_calibrationMode != CalibrationModeCalibrating) {
int axis = _rgFunctionAxis[rollFunction]; int axis = _rgFunctionAxis[rollFunction];
float roll = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis]); float roll = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis], _deadband);
axis = _rgFunctionAxis[pitchFunction]; axis = _rgFunctionAxis[pitchFunction];
float pitch = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis]); float pitch = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis], _deadband);
axis = _rgFunctionAxis[yawFunction]; axis = _rgFunctionAxis[yawFunction];
float yaw = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis]); float yaw = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis],_deadband);
axis = _rgFunctionAxis[throttleFunction]; axis = _rgFunctionAxis[throttleFunction];
float throttle = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis]); float throttle = _adjustRange(_rgAxisValues[axis], _rgCalibration[axis], _throttleMode==ThrottleModeDownZero?false:_deadband);
if ( _accumulator ) {
static float throttle_accu = 0.f;
throttle_accu += throttle*(40/1000.f); //for throttle to change from min to max it will take 1000ms (40ms is a loop time)
throttle_accu = std::max(static_cast<float>(-1.f), std::min(throttle_accu, static_cast<float>(1.f)));
throttle = throttle_accu;
}
float roll_limited = std::max(static_cast<float>(-M_PI_4), std::min(roll, static_cast<float>(M_PI_4))); float roll_limited = std::max(static_cast<float>(-M_PI_4), std::min(roll, static_cast<float>(M_PI_4)));
float pitch_limited = std::max(static_cast<float>(-M_PI_4), std::min(pitch, static_cast<float>(M_PI_4))); float pitch_limited = std::max(static_cast<float>(-M_PI_4), std::min(pitch, static_cast<float>(M_PI_4)));
@ -512,6 +544,11 @@ void Joystick::setThrottleMode(int mode)
} }
_throttleMode = (ThrottleMode_t)mode; _throttleMode = (ThrottleMode_t)mode;
if (_throttleMode == ThrottleModeDownZero) {
setAccumulator(false);
}
_saveSettings(); _saveSettings();
emit throttleModeChanged(_throttleMode); emit throttleModeChanged(_throttleMode);
} }
@ -529,6 +566,31 @@ void Joystick::setExponential(bool expo)
emit exponentialChanged(_exponential); emit exponentialChanged(_exponential);
} }
bool Joystick::accumulator(void)
{
return _accumulator;
}
void Joystick::setAccumulator(bool accu)
{
_accumulator = accu;
_saveSettings();
emit accumulatorChanged(_accumulator);
}
bool Joystick::deadband(void)
{
return _deadband;
}
void Joystick::setDeadband(bool deadband)
{
_deadband = deadband;
_saveSettings();
}
void Joystick::startCalibrationMode(CalibrationMode_t mode) void Joystick::startCalibrationMode(CalibrationMode_t mode)
{ {
if (mode == CalibrationModeOff) { if (mode == CalibrationModeOff) {

18
src/Joystick/Joystick.h

@ -34,6 +34,7 @@ public:
int min; int min;
int max; int max;
int center; int center;
int deadband;
bool reversed; bool reversed;
} Calibration_t; } Calibration_t;
@ -65,7 +66,8 @@ public:
Q_INVOKABLE QString getButtonAction(int button); Q_INVOKABLE QString getButtonAction(int button);
Q_PROPERTY(int throttleMode READ throttleMode WRITE setThrottleMode NOTIFY throttleModeChanged) Q_PROPERTY(int throttleMode READ throttleMode WRITE setThrottleMode NOTIFY throttleModeChanged)
Q_PROPERTY(int exponential READ exponential WRITE setExponential NOTIFY exponentialChanged) Q_PROPERTY(bool exponential READ exponential WRITE setExponential NOTIFY exponentialChanged)
Q_PROPERTY(bool accumulator READ accumulator WRITE setAccumulator NOTIFY accumulatorChanged)
// Property accessors // Property accessors
@ -93,6 +95,12 @@ public:
bool exponential(void); bool exponential(void);
void setExponential(bool expo); void setExponential(bool expo);
bool accumulator(void);
void setAccumulator(bool accu);
bool deadband(void);
void setDeadband(bool accu);
typedef enum { typedef enum {
CalibrationModeOff, // Not calibrating CalibrationModeOff, // Not calibrating
CalibrationModeMonitor, // Monitors are active, continue to send to vehicle if already polling CalibrationModeMonitor, // Monitors are active, continue to send to vehicle if already polling
@ -118,6 +126,8 @@ signals:
void exponentialChanged(bool exponential); void exponentialChanged(bool exponential);
void accumulatorChanged(bool accumulator);
void enabledChanged(bool enabled); void enabledChanged(bool enabled);
/// Signal containing new joystick information /// Signal containing new joystick information
@ -133,7 +143,7 @@ signals:
protected: protected:
void _saveSettings(void); void _saveSettings(void);
void _loadSettings(void); void _loadSettings(void);
float _adjustRange(int value, Calibration_t calibration); float _adjustRange(int value, Calibration_t calibration, bool withDeadbands);
void _buttonAction(const QString& action); void _buttonAction(const QString& action);
bool _validAxis(int axis); bool _validAxis(int axis);
bool _validButton(int button); bool _validButton(int button);
@ -175,6 +185,8 @@ protected:
ThrottleMode_t _throttleMode; ThrottleMode_t _throttleMode;
bool _exponential; bool _exponential;
bool _accumulator;
bool _deadband;
Vehicle* _activeVehicle; Vehicle* _activeVehicle;
bool _pollingStartedForCalibration; bool _pollingStartedForCalibration;
@ -189,6 +201,8 @@ private:
static const char* _buttonActionSettingsKey; static const char* _buttonActionSettingsKey;
static const char* _throttleModeSettingsKey; static const char* _throttleModeSettingsKey;
static const char* _exponentialSettingsKey; static const char* _exponentialSettingsKey;
static const char* _accumulatorSettingsKey;
static const char* _deadbandSettingsKey;
}; };
#endif #endif

10
src/MissionManager/MavCmdInfoCommon.json

@ -308,8 +308,8 @@
{ {
"id": 84, "id": 84,
"rawName": "MAV_CMD_NAV_VTOL_TAKEOFF", "rawName": "MAV_CMD_NAV_VTOL_TAKEOFF",
"friendlyName": "VTOL takeoff", "friendlyName": "VTOL takeoff and transition",
"description": "Takeoff from ground using VTOL mode.", "description": "Takeoff in VTOL mode, transition to forward flight and fly to the specified location.",
"specifiesCoordinate": true, "specifiesCoordinate": true,
"friendlyEdit": true, "friendlyEdit": true,
"category": "VTOL", "category": "VTOL",
@ -323,8 +323,8 @@
{ {
"id": 85, "id": 85,
"rawName": "MAV_CMD_NAV_VTOL_LAND", "rawName": "MAV_CMD_NAV_VTOL_LAND",
"friendlyName": "VTOL land", "friendlyName": "VTOL transition and land",
"description": "Land using VTOL mode.", "description": "Transition to VTOL mode and land.",
"specifiesCoordinate": true, "specifiesCoordinate": true,
"friendlyEdit": true, "friendlyEdit": true,
"category": "VTOL", "category": "VTOL",
@ -975,7 +975,7 @@
"id": 3000, "id": 3000,
"rawName": "MAV_CMD_DO_VTOL_TRANSITION", "rawName": "MAV_CMD_DO_VTOL_TRANSITION",
"friendlyName": "VTOL Transition", "friendlyName": "VTOL Transition",
"description": "Perform flight mode transition", "description": "Perform flight mode transition.",
"category": "VTOL", "category": "VTOL",
"param1": { "param1": {
"label": "Mode:", "label": "Mode:",

60
src/VehicleSetup/JoystickConfig.qml

@ -72,7 +72,7 @@ SetupPage {
Item { Item {
property int axisValue: 0 property int axisValue: 0
property int deadbandValue: 0
property int __lastAxisValue: 0 property int __lastAxisValue: 0
readonly property int __axisValueMaxJitter: 100 readonly property int __axisValueMaxJitter: 100
@ -87,6 +87,20 @@ SetupPage {
color: __barColor color: __barColor
} }
// Deadband
Rectangle {
id: deadbandBar
anchors.verticalCenter: parent.verticalCenter
x: _deadbandPosition
width: _deadbandWidth
height: parent.height / 2
color: "#8c161a"
property real _percentDeadband: ((2 * deadbandValue) / (32768.0 * 2))
property real _deadbandWidth: parent.width * _percentDeadband
property real _deadbandPosition: (parent.width - _deadbandWidth) / 2
}
// Center point // Center point
Rectangle { Rectangle {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
@ -126,13 +140,15 @@ SetupPage {
duration: 1500 duration: 1500
} }
/*
// Axis value debugger // Axis value debugger
/*
QGCLabel { QGCLabel {
anchors.fill: parent anchors.fill: parent
text: axisValue text: axisValue
} }
*/ */
} }
} // Component - axisMonitorDisplayComponent } // Component - axisMonitorDisplayComponent
@ -180,6 +196,8 @@ SetupPage {
target: controller target: controller
onRollAxisValueChanged: rollLoader.item.axisValue = value onRollAxisValueChanged: rollLoader.item.axisValue = value
onRollAxisDeadbandChanged: rollLoader.item.deadbandValue = value
} }
} }
@ -210,6 +228,9 @@ SetupPage {
target: controller target: controller
onPitchAxisValueChanged: pitchLoader.item.axisValue = value onPitchAxisValueChanged: pitchLoader.item.axisValue = value
onPitchAxisDeadbandChanged: pitchLoader.item.deadbandValue = value
} }
} }
@ -240,6 +261,8 @@ SetupPage {
target: controller target: controller
onYawAxisValueChanged: yawLoader.item.axisValue = value onYawAxisValueChanged: yawLoader.item.axisValue = value
onYawAxisDeadbandChanged: yawLoader.item.deadbandValue = value
} }
} }
@ -270,6 +293,8 @@ SetupPage {
target: controller target: controller
onThrottleAxisValueChanged: throttleLoader.item.axisValue = value onThrottleAxisValueChanged: throttleLoader.item.axisValue = value
onThrottleAxisDeadbandChanged: throttleLoader.item.deadbandValue = value
} }
} }
} // Column - Attitude Control labels } // Column - Attitude Control labels
@ -382,6 +407,21 @@ SetupPage {
onClicked: _activeJoystick.throttleMode = 0 onClicked: _activeJoystick.throttleMode = 0
} }
Row {
x: 20
width: parent.width
spacing: ScreenTools.defaultFontPixelWidth
visible: _activeJoystick.throttleMode == 0
QGCCheckBox {
id: accumulator
checked: _activeJoystick.accumulator
text: qsTr("Spring loaded throttle smoothing")
onClicked: _activeJoystick.accumulator = checked
}
}
QGCRadioButton { QGCRadioButton {
exclusiveGroup: throttleModeExclusiveGroup exclusiveGroup: throttleModeExclusiveGroup
text: qsTr("Full down stick is zero throttle") text: qsTr("Full down stick is zero throttle")
@ -435,6 +475,20 @@ SetupPage {
onActivated: _activeVehicle.joystickMode = index onActivated: _activeVehicle.joystickMode = index
} }
} }
Row {
width: parent.width
spacing: ScreenTools.defaultFontPixelWidth
visible: advancedSettings.checked
QGCCheckBox {
id: deadband
checked: controller.deadbandToggle
text: qsTr("Deadbands")
onClicked: controller.deadbandToggle = checked
}
}
} }
} // Column - left column } // Column - left column
@ -697,3 +751,5 @@ SetupPage {
} // Item } // Item
} // Component - pageComponent } // Component - pageComponent
} // SetupPage } // SetupPage

75
src/VehicleSetup/JoystickConfigController.cc

@ -210,6 +210,18 @@ void JoystickConfigController::cancelButtonClicked(void)
_stopCalibration(); _stopCalibration();
} }
bool JoystickConfigController::getDeadbandToggle() {
return _activeJoystick->deadband();
}
void JoystickConfigController::setDeadbandToggle(bool deadband) {
_activeJoystick->setDeadband(deadband);
_signalAllAttiudeValueChanges();
emit deadbandToggled(deadband);
}
void JoystickConfigController::_saveAllTrims(void) void JoystickConfigController::_saveAllTrims(void)
{ {
// We save all trims as the first step. At this point no axes are mapped but it should still // We save all trims as the first step. At this point no axes are mapped but it should still
@ -224,16 +236,28 @@ void JoystickConfigController::_saveAllTrims(void)
_advanceState(); _advanceState();
} }
void JoystickConfigController::_axisDeadbandChanged(int axis, int value)
{
value = abs(value)<_calValidMaxValue?abs(value):_calValidMaxValue;
_rgAxisInfo[axis].deadband = value;
qCDebug(JoystickConfigControllerLog) << "Axis:" << axis << "Deadband:" << _rgAxisInfo[axis].deadband;
}
/// @brief Waits for the sticks to be centered, enabling Next when done. /// @brief Waits for the sticks to be centered, enabling Next when done.
void JoystickConfigController::_inputCenterWaitBegin(Joystick::AxisFunction_t function, int axis, int value) void JoystickConfigController::_inputCenterWaitBegin(Joystick::AxisFunction_t function, int axis, int value)
{ {
Q_UNUSED(function); Q_UNUSED(function);
Q_UNUSED(axis);
Q_UNUSED(value);
// FIXME: Doesn't wait for center //sensing deadband
if (abs(value)*1.1f>_rgAxisInfo[axis].deadband) { //add 10% on top of existing deadband
_axisDeadbandChanged(axis,abs(value)*1.1f);
}
_nextButton->setEnabled(true); _nextButton->setEnabled(true);
// FIXME: Doesn't wait for center
} }
bool JoystickConfigController::_stickSettleComplete(int axis, int value) bool JoystickConfigController::_stickSettleComplete(int axis, int value)
@ -420,6 +444,7 @@ void JoystickConfigController::_resetInternalCalibrationValues(void)
struct AxisInfo* info = &_rgAxisInfo[i]; struct AxisInfo* info = &_rgAxisInfo[i];
info->function = Joystick::maxFunction; info->function = Joystick::maxFunction;
info->reversed = false; info->reversed = false;
info->deadband = 0;
info->axisMin = JoystickConfigController::_calCenterPoint; info->axisMin = JoystickConfigController::_calCenterPoint;
info->axisMax = JoystickConfigController::_calCenterPoint; info->axisMax = JoystickConfigController::_calCenterPoint;
info->axisTrim = JoystickConfigController::_calCenterPoint; info->axisTrim = JoystickConfigController::_calCenterPoint;
@ -457,6 +482,7 @@ void JoystickConfigController::_setInternalCalibrationValuesFromSettings(void)
info->axisMin = calibration.min; info->axisMin = calibration.min;
info->axisMax = calibration.max; info->axisMax = calibration.max;
info->reversed = calibration.reversed; info->reversed = calibration.reversed;
info->deadband = calibration.deadband;
qCDebug(JoystickConfigControllerLog) << "Read settings name:axis:min:max:trim:reversed" << joystick->name() << axis << info->axisMin << info->axisMax << info->axisTrim << info->reversed; qCDebug(JoystickConfigControllerLog) << "Read settings name:axis:min:max:trim:reversed" << joystick->name() << axis << info->axisMin << info->axisMax << info->axisTrim << info->reversed;
} }
@ -512,6 +538,7 @@ void JoystickConfigController::_validateCalibration(void)
info->axisMin = _calDefaultMinValue; info->axisMin = _calDefaultMinValue;
info->axisMax = _calDefaultMaxValue; info->axisMax = _calDefaultMaxValue;
info->axisTrim = info->axisMin + ((info->axisMax - info->axisMin) / 2); info->axisTrim = info->axisMin + ((info->axisMax - info->axisMin) / 2);
info->deadband = 0;
info->reversed = false; info->reversed = false;
} }
} }
@ -534,6 +561,7 @@ void JoystickConfigController::_writeCalibration(void)
calibration.min = info->axisMin; calibration.min = info->axisMin;
calibration.max = info->axisMax; calibration.max = info->axisMax;
calibration.reversed = info->reversed; calibration.reversed = info->reversed;
calibration.deadband = info->deadband;
joystick->setCalibration(axis, calibration); joystick->setCalibration(axis, calibration);
} }
@ -664,6 +692,42 @@ int JoystickConfigController::throttleAxisValue(void)
} }
} }
int JoystickConfigController::rollAxisDeadband(void)
{
if ((_rgFunctionAxisMapping[Joystick::rollFunction] != _axisNoAxis) && (_activeJoystick->deadband())) {
return _rgAxisInfo[_rgFunctionAxisMapping[Joystick::rollFunction]].deadband;
} else {
return 0;
}
}
int JoystickConfigController::pitchAxisDeadband(void)
{
if ((_rgFunctionAxisMapping[Joystick::pitchFunction] != _axisNoAxis) && (_activeJoystick->deadband())) {
return _rgAxisInfo[_rgFunctionAxisMapping[Joystick::pitchFunction]].deadband;
} else {
return 0;
}
}
int JoystickConfigController::yawAxisDeadband(void)
{
if ((_rgFunctionAxisMapping[Joystick::yawFunction] != _axisNoAxis) && (_activeJoystick->deadband())) {
return _rgAxisInfo[_rgFunctionAxisMapping[Joystick::yawFunction]].deadband;
} else {
return 0;
}
}
int JoystickConfigController::throttleAxisDeadband(void)
{
if ((_rgFunctionAxisMapping[Joystick::throttleFunction] != _axisNoAxis) && (_activeJoystick->deadband())) {
return _rgAxisInfo[_rgFunctionAxisMapping[Joystick::throttleFunction]].deadband;
} else {
return 0;
}
}
bool JoystickConfigController::rollAxisMapped(void) bool JoystickConfigController::rollAxisMapped(void)
{ {
return _rgFunctionAxisMapping[Joystick::rollFunction] != _axisNoAxis; return _rgFunctionAxisMapping[Joystick::rollFunction] != _axisNoAxis;
@ -731,6 +795,11 @@ void JoystickConfigController::_signalAllAttiudeValueChanges(void)
emit pitchAxisReversedChanged(pitchAxisReversed()); emit pitchAxisReversedChanged(pitchAxisReversed());
emit yawAxisReversedChanged(yawAxisReversed()); emit yawAxisReversedChanged(yawAxisReversed());
emit throttleAxisReversedChanged(throttleAxisReversed()); emit throttleAxisReversedChanged(throttleAxisReversed());
emit rollAxisDeadbandChanged(rollAxisDeadband());
emit pitchAxisDeadbandChanged(pitchAxisDeadband());
emit yawAxisDeadbandChanged(yawAxisDeadband());
emit throttleAxisDeadbandChanged(throttleAxisDeadband());
} }
void JoystickConfigController::_activeJoystickChanged(Joystick* joystick) void JoystickConfigController::_activeJoystickChanged(Joystick* joystick)

24
src/VehicleSetup/JoystickConfigController.h

@ -57,11 +57,18 @@ public:
Q_PROPERTY(int yawAxisValue READ yawAxisValue NOTIFY yawAxisValueChanged) Q_PROPERTY(int yawAxisValue READ yawAxisValue NOTIFY yawAxisValueChanged)
Q_PROPERTY(int throttleAxisValue READ throttleAxisValue NOTIFY throttleAxisValueChanged) Q_PROPERTY(int throttleAxisValue READ throttleAxisValue NOTIFY throttleAxisValueChanged)
Q_PROPERTY(int rollAxisDeadband READ rollAxisDeadband NOTIFY rollAxisDeadbandChanged)
Q_PROPERTY(int pitchAxisDeadband READ pitchAxisDeadband NOTIFY pitchAxisDeadbandChanged)
Q_PROPERTY(int yawAxisDeadband READ yawAxisDeadband NOTIFY yawAxisDeadbandChanged)
Q_PROPERTY(int throttleAxisDeadband READ throttleAxisDeadband NOTIFY throttleAxisDeadbandChanged)
Q_PROPERTY(int rollAxisReversed READ rollAxisReversed NOTIFY rollAxisReversedChanged) Q_PROPERTY(int rollAxisReversed READ rollAxisReversed NOTIFY rollAxisReversedChanged)
Q_PROPERTY(int pitchAxisReversed READ pitchAxisReversed NOTIFY pitchAxisReversedChanged) Q_PROPERTY(int pitchAxisReversed READ pitchAxisReversed NOTIFY pitchAxisReversedChanged)
Q_PROPERTY(int yawAxisReversed READ yawAxisReversed NOTIFY yawAxisReversedChanged) Q_PROPERTY(int yawAxisReversed READ yawAxisReversed NOTIFY yawAxisReversedChanged)
Q_PROPERTY(int throttleAxisReversed READ throttleAxisReversed NOTIFY throttleAxisReversedChanged) Q_PROPERTY(int throttleAxisReversed READ throttleAxisReversed NOTIFY throttleAxisReversedChanged)
Q_PROPERTY(bool deadbandToggle READ getDeadbandToggle WRITE setDeadbandToggle NOTIFY deadbandToggled)
Q_PROPERTY(QString imageHelp MEMBER _imageHelp NOTIFY imageHelpChanged) Q_PROPERTY(QString imageHelp MEMBER _imageHelp NOTIFY imageHelpChanged)
Q_INVOKABLE void cancelButtonClicked(void); Q_INVOKABLE void cancelButtonClicked(void);
@ -74,6 +81,11 @@ public:
int yawAxisValue(void); int yawAxisValue(void);
int throttleAxisValue(void); int throttleAxisValue(void);
int rollAxisDeadband(void);
int pitchAxisDeadband(void);
int yawAxisDeadband(void);
int throttleAxisDeadband(void);
bool rollAxisMapped(void); bool rollAxisMapped(void);
bool pitchAxisMapped(void); bool pitchAxisMapped(void);
bool yawAxisMapped(void); bool yawAxisMapped(void);
@ -84,6 +96,9 @@ public:
bool yawAxisReversed(void); bool yawAxisReversed(void);
bool throttleAxisReversed(void); bool throttleAxisReversed(void);
bool getDeadbandToggle(void);
void setDeadbandToggle(bool);
int axisCount(void); int axisCount(void);
signals: signals:
@ -99,11 +114,18 @@ signals:
void yawAxisValueChanged(int value); void yawAxisValueChanged(int value);
void throttleAxisValueChanged(int value); void throttleAxisValueChanged(int value);
void rollAxisDeadbandChanged(int value);
void pitchAxisDeadbandChanged(int value);
void yawAxisDeadbandChanged(int value);
void throttleAxisDeadbandChanged(int value);
void rollAxisReversedChanged(bool reversed); void rollAxisReversedChanged(bool reversed);
void pitchAxisReversedChanged(bool reversed); void pitchAxisReversedChanged(bool reversed);
void yawAxisReversedChanged(bool reversed); void yawAxisReversedChanged(bool reversed);
void throttleAxisReversedChanged(bool reversed); void throttleAxisReversedChanged(bool reversed);
void deadbandToggled(bool value);
void imageHelpChanged(QString source); void imageHelpChanged(QString source);
// @brief Signalled when in unit test mode and a message box should be displayed by the next button // @brief Signalled when in unit test mode and a message box should be displayed by the next button
@ -112,6 +134,7 @@ signals:
private slots: private slots:
void _activeJoystickChanged(Joystick* joystick); void _activeJoystickChanged(Joystick* joystick);
void _axisValueChanged(int axis, int value); void _axisValueChanged(int axis, int value);
void _axisDeadbandChanged(int axis, int value);
private: private:
/// @brief The states of the calibration state machine. /// @brief The states of the calibration state machine.
@ -144,6 +167,7 @@ private:
int axisMin; ///< Minimum axis value int axisMin; ///< Minimum axis value
int axisMax; ///< Maximum axis value int axisMax; ///< Maximum axis value
int axisTrim; ///< Trim position int axisTrim; ///< Trim position
int deadband; ///< Deadband
}; };
Joystick* _activeJoystick; Joystick* _activeJoystick;

4
src/qgcunittest/UnitTestList.cc

@ -47,7 +47,6 @@ UT_REGISTER_TEST(MissionControllerTest)
UT_REGISTER_TEST(MissionManagerTest) UT_REGISTER_TEST(MissionManagerTest)
UT_REGISTER_TEST(RadioConfigTest) UT_REGISTER_TEST(RadioConfigTest)
UT_REGISTER_TEST(TCPLinkTest) UT_REGISTER_TEST(TCPLinkTest)
UT_REGISTER_TEST(FileManagerTest)
UT_REGISTER_TEST(ParameterManagerTest) UT_REGISTER_TEST(ParameterManagerTest)
UT_REGISTER_TEST(MissionCommandTreeTest) UT_REGISTER_TEST(MissionCommandTreeTest)
UT_REGISTER_TEST(LogDownloadTest) UT_REGISTER_TEST(LogDownloadTest)
@ -58,3 +57,6 @@ UT_REGISTER_TEST(LogDownloadTest)
// FIXME: Temporarily disabled until this can be stabilized // FIXME: Temporarily disabled until this can be stabilized
//UT_REGISTER_TEST(MainWindowTest) //UT_REGISTER_TEST(MainWindowTest)
// Onboard file support has been removed until it can be make to work correctly
//UT_REGISTER_TEST(FileManagerTest)

12
src/ui/MainWindow.cc

@ -301,12 +301,17 @@ void MainWindow::_buildCommonWidgets(void)
logPlayer = new QGCMAVLinkLogPlayer(statusBar()); logPlayer = new QGCMAVLinkLogPlayer(statusBar());
statusBar()->addPermanentWidget(logPlayer); statusBar()->addPermanentWidget(logPlayer);
// Populate widget menu
for (int i = 0, end = ARRAY_SIZE(rgDockWidgetNames); i < end; i++) { for (int i = 0, end = ARRAY_SIZE(rgDockWidgetNames); i < end; i++) {
if (i == ONBOARD_FILES) {
// Temporarily removed until twe can fix all the problems with it
continue;
}
const char* pDockWidgetName = rgDockWidgetNames[i]; const char* pDockWidgetName = rgDockWidgetNames[i];
// Add to menu // Add to menu
QAction* action = new QAction(tr(pDockWidgetName), this); QAction* action = new QAction(pDockWidgetName, this);
action->setCheckable(true); action->setCheckable(true);
action->setData(i); action->setData(i);
connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction); connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction);
@ -318,6 +323,11 @@ void MainWindow::_buildCommonWidgets(void)
/// Shows or hides the specified dock widget, creating if necessary /// Shows or hides the specified dock widget, creating if necessary
void MainWindow::_showDockWidget(const QString& name, bool show) void MainWindow::_showDockWidget(const QString& name, bool show)
{ {
if (name == rgDockWidgetNames[ONBOARD_FILES]) {
// Temporarily disabled due to bugs
return;
}
// Create the inner widget if we need to // Create the inner widget if we need to
if (!_mapName2DockWidget.contains(name)) { if (!_mapName2DockWidget.contains(name)) {
if(!_createInnerDockWidget(name)) { if(!_createInnerDockWidget(name)) {

4
src/ui/toolbar/MainToolBar.qml

@ -393,6 +393,7 @@ Rectangle {
property bool vehicleConnectionLost: activeVehicle ? activeVehicle.connectionLost : false property bool vehicleConnectionLost: activeVehicle ? activeVehicle.connectionLost : false
Loader { Loader {
id: indicatorLoader
source: activeVehicle && !parent.vehicleConnectionLost ? "MainToolBarIndicators.qml" : "" source: activeVehicle && !parent.vehicleConnectionLost ? "MainToolBarIndicators.qml" : ""
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -408,7 +409,6 @@ Rectangle {
anchors.right: disconnectButton.left anchors.right: disconnectButton.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
visible: parent.vehicleConnectionLost visible: parent.vehicleConnectionLost
} }
QGCButton { QGCButton {
@ -427,7 +427,7 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
visible: parent.x < x && !disconnectButton.visible && source != "" visible: x > indicatorLoader.x + indicatorLoader.width && !disconnectButton.visible && source != ""
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
source: activeVehicle ? activeVehicle.brandImage : "" source: activeVehicle ? activeVehicle.brandImage : ""
} }

Loading…
Cancel
Save