mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +01:00
Merge remote-tracking branch 'origin/next' into thread/OP-1525_Acro_GUI
This commit is contained in:
commit
b794c87d3b
@ -116,6 +116,8 @@
|
||||
#define USB_LED_OFF
|
||||
#endif
|
||||
|
||||
#define CONNECTED_LIVE 8
|
||||
|
||||
/* Local type definitions */
|
||||
|
||||
struct pios_rfm22b_transition {
|
||||
@ -358,7 +360,7 @@ static const uint8_t reg_72[] = { 0x30, 0x48, 0x48, 0x48, 0x48, 0x60, 0x90, 0xCD
|
||||
|
||||
static const uint8_t packet_time[] = { 80, 40, 25, 15, 13, 10, 8, 6, 5 };
|
||||
static const uint8_t packet_time_ppm[] = { 26, 25, 25, 15, 13, 10, 8, 6, 5 };
|
||||
static const uint8_t num_channels[] = { 4, 4, 4, 6, 8, 8, 10, 12, 16 };
|
||||
static const uint8_t num_channels[] = { 32, 32, 32, 32, 32, 32, 32, 32, 32 };
|
||||
|
||||
static struct pios_rfm22b_dev *g_rfm22b_dev = NULL;
|
||||
|
||||
@ -606,6 +608,8 @@ void PIOS_RFM22B_SetChannelConfig(uint32_t rfm22b_id, enum rfm22b_datarate datar
|
||||
}
|
||||
}
|
||||
|
||||
rfm22b_dev->num_channels = num_found;
|
||||
|
||||
// Calculate the maximum packet length from the datarate.
|
||||
float bytes_per_period = (float)data_rate[datarate] * (float)(rfm22b_dev->packet_time - 2) / 9000;
|
||||
|
||||
@ -797,7 +801,6 @@ bool PIOS_RFM22B_TransmitPacket(uint32_t rfm22b_id, uint8_t *p, uint8_t len)
|
||||
rfm22_write(rfm22b_dev, RFM22_interrupt_enable2, 0x00);
|
||||
|
||||
// set the tx power
|
||||
rfm22b_dev->tx_power = 0x7;
|
||||
rfm22_write(rfm22b_dev, RFM22_tx_power, RFM22_tx_pwr_lna_sw | rfm22b_dev->tx_power);
|
||||
|
||||
// TUNE mode
|
||||
@ -1356,7 +1359,7 @@ static enum pios_radio_event rfm22_init(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
rfm22b_dev->packet_start_ticks = 0;
|
||||
rfm22b_dev->tx_complete_ticks = 0;
|
||||
rfm22b_dev->rfm22b_state = RFM22B_STATE_INITIALIZING;
|
||||
rfm22b_dev->on_sync_channel = false;
|
||||
rfm22b_dev->connected_timeout = 0;
|
||||
|
||||
// software reset the RF chip .. following procedure according to Si4x3x Errata (rev. B)
|
||||
rfm22_write_claim(rfm22b_dev, RFM22_op_and_func_ctrl1, RFM22_opfc1_swres);
|
||||
@ -1961,12 +1964,16 @@ static enum pios_radio_event radio_receivePacket(struct pios_rfm22b_dev *radio_d
|
||||
(radio_dev->rx_in_cb)(radio_dev->rx_in_context, p, data_len, NULL, &rx_need_yield);
|
||||
}
|
||||
|
||||
// We only synchronize the clock on packets from our coordinator on the sync channel.
|
||||
if (!rfm22_isCoordinator(radio_dev) && (radio_dev->rx_destination_id == rfm22_destinationID(radio_dev)) && (radio_dev->channel_index == 0)) {
|
||||
/*
|
||||
* If the packet is valid and destined for us we synchronize the clock.
|
||||
*/
|
||||
if (!rfm22_isCoordinator(radio_dev) &&
|
||||
radio_dev->rx_destination_id == rfm22_destinationID(radio_dev)) {
|
||||
rfm22_synchronizeClock(radio_dev);
|
||||
radio_dev->stats.link_state = OPLINKSTATUS_LINKSTATE_CONNECTED;
|
||||
radio_dev->on_sync_channel = false;
|
||||
}
|
||||
|
||||
radio_dev->connected_timeout = CONNECTED_LIVE;
|
||||
} else {
|
||||
ret_event = RADIO_EVENT_RX_COMPLETE;
|
||||
}
|
||||
@ -2162,14 +2169,14 @@ static void rfm22_synchronizeClock(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
portTickType start_time = rfm22b_dev->packet_start_ticks;
|
||||
|
||||
// This packet was transmitted on channel 0, calculate the time delta that will force us to transmit on channel 0 at the time this packet started.
|
||||
uint8_t num_chan = num_channels[rfm22b_dev->datarate];
|
||||
uint16_t frequency_hop_cycle_time = rfm22b_dev->packet_time * num_chan;
|
||||
uint16_t frequency_hop_cycle_time = rfm22b_dev->packet_time * rfm22b_dev->num_channels;
|
||||
uint16_t time_delta = start_time % frequency_hop_cycle_time;
|
||||
|
||||
// Calculate the adjustment for the preamble
|
||||
uint8_t offset = (uint8_t)ceil(35000.0F / data_rate[rfm22b_dev->datarate]);
|
||||
|
||||
rfm22b_dev->time_delta = frequency_hop_cycle_time - time_delta + offset;
|
||||
rfm22b_dev->time_delta = frequency_hop_cycle_time - time_delta + offset +
|
||||
rfm22b_dev->packet_time * rfm22b_dev->channel_index;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2224,14 +2231,11 @@ static bool rfm22_timeToSend(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
static uint8_t rfm22_calcChannel(struct pios_rfm22b_dev *rfm22b_dev, uint8_t index)
|
||||
{
|
||||
// Make sure we don't index outside of the range.
|
||||
uint8_t num_chan = num_channels[rfm22b_dev->datarate];
|
||||
uint8_t idx = index % num_chan;
|
||||
uint8_t idx = index % rfm22b_dev->num_channels;
|
||||
|
||||
// Are we switching to a new channel?
|
||||
if (idx != rfm22b_dev->channel_index) {
|
||||
// If the on_sync_channel flag is set, it means that we were on the sync channel, but no packet was received, so transition to a non-connected state.
|
||||
if (!rfm22_isCoordinator(rfm22b_dev) && (rfm22b_dev->channel_index == 0) && rfm22b_dev->on_sync_channel) {
|
||||
rfm22b_dev->on_sync_channel = false;
|
||||
if (!rfm22_isCoordinator(rfm22b_dev) && rfm22b_dev->connected_timeout == 0) {
|
||||
|
||||
// Set the link state to disconnected.
|
||||
if (rfm22b_dev->stats.link_state == OPLINKSTATUS_LINKSTATE_CONNECTED) {
|
||||
@ -2242,14 +2246,14 @@ static uint8_t rfm22_calcChannel(struct pios_rfm22b_dev *rfm22b_dev, uint8_t ind
|
||||
}
|
||||
}
|
||||
|
||||
// Stay on the sync channel.
|
||||
// Stay on first channel.
|
||||
idx = 0;
|
||||
} else if (idx == 0) {
|
||||
// If we're switching to the sync channel, set a flag that can be used to detect if a packet was received.
|
||||
rfm22b_dev->on_sync_channel = true;
|
||||
}
|
||||
|
||||
rfm22b_dev->channel_index = idx;
|
||||
if (rfm22b_dev->connected_timeout > 0)
|
||||
rfm22b_dev->connected_timeout--;
|
||||
|
||||
}
|
||||
|
||||
return rfm22b_dev->channels[idx];
|
||||
@ -2265,8 +2269,7 @@ static uint8_t rfm22_calcChannelFromClock(struct pios_rfm22b_dev *rfm22b_dev)
|
||||
portTickType time = rfm22_coordinatorTime(rfm22b_dev, xTaskGetTickCount());
|
||||
// Divide time into 8ms blocks. Coordinator sends in first 2 ms, and remote send in 5th and 6th ms.
|
||||
// Channel changes occur in the last 2 ms.
|
||||
uint8_t num_chan = num_channels[rfm22b_dev->datarate];
|
||||
uint8_t n = (time / rfm22b_dev->packet_time) % num_chan;
|
||||
uint8_t n = (time / rfm22b_dev->packet_time) % rfm22b_dev->num_channels;
|
||||
|
||||
return rfm22_calcChannel(rfm22b_dev, n);
|
||||
}
|
||||
|
@ -780,7 +780,7 @@ struct pios_rfm22b_dev {
|
||||
portTickType packet_start_ticks;
|
||||
portTickType tx_complete_ticks;
|
||||
portTickType time_delta;
|
||||
bool on_sync_channel;
|
||||
uint8_t connected_timeout;
|
||||
};
|
||||
|
||||
|
||||
|
@ -411,26 +411,6 @@ void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
|
||||
setComboCurrentIndex(m_aircraft->multiMotorChannelBox4, multi.VTOLMotorSW);
|
||||
setComboCurrentIndex(m_aircraft->multiMotorChannelBox5, multi.VTOLMotorW);
|
||||
setComboCurrentIndex(m_aircraft->multiMotorChannelBox6, multi.VTOLMotorNW);
|
||||
|
||||
// Now, read the 1st mixer R/P/Y levels and initialize the mix sliders.
|
||||
// This assumes that all vectors are identical - if not, the user should use the
|
||||
// "custom" setting.
|
||||
|
||||
int channel = m_aircraft->multiMotorChannelBox1->currentIndex() - 1;
|
||||
if (channel > -1) {
|
||||
// get motor 1 value for Pitch
|
||||
double value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_PITCH);
|
||||
m_aircraft->mrPitchMixLevel->setValue(qRound(value / 1.27));
|
||||
|
||||
// get motor 2 value for Yaw and Roll
|
||||
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
|
||||
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW);
|
||||
setYawMixLevel(qRound(value / 1.27));
|
||||
|
||||
channel = m_aircraft->multiMotorChannelBox2->currentIndex() - 1;
|
||||
value = getMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_ROLL);
|
||||
m_aircraft->mrRollMixLevel->setValue(-qRound(value / 1.27));
|
||||
}
|
||||
} else if (frameType == "HexaCoax") {
|
||||
// Motors 1/2/3 4/5/6 are: NW/W NE/E S/SE
|
||||
setComboCurrentIndex(m_aircraft->multiMotorChannelBox1, multi.VTOLMotorNW);
|
||||
@ -480,7 +460,9 @@ void ConfigMultiRotorWidget::refreshWidgetsValues(QString frameType)
|
||||
// Now, read mixing values stored on board and applies values on sliders.
|
||||
m_aircraft->mrPitchMixLevel->setValue(getMixerValue(mixer, "MixerValuePitch"));
|
||||
m_aircraft->mrRollMixLevel->setValue(getMixerValue(mixer, "MixerValueRoll"));
|
||||
m_aircraft->mrYawMixLevel->setValue(getMixerValue(mixer, "MixerValueYaw"));
|
||||
|
||||
// MixerValueYaw : negative = reversed
|
||||
setYawMixLevel(getMixerValue(mixer, "MixerValueYaw"));
|
||||
|
||||
updateAirframe(frameType);
|
||||
}
|
||||
@ -743,7 +725,8 @@ QString ConfigMultiRotorWidget::updateConfigObjectsFromWidgets()
|
||||
setMixerType(mixer, channel, VehicleConfig::MIXERTYPE_SERVO);
|
||||
|
||||
// Tricopter : Yaw mix slider value applies to servo (was fixed)
|
||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, getMixerValue(mixer, "MixerValueYaw") * 1.27);
|
||||
// Get absolute MixerValueYaw, no servo reverse when Reverse All Motors is checked
|
||||
setMixerVectorValue(mixer, channel, VehicleConfig::MIXERVECTOR_YAW, abs(getMixerValue(mixer, "MixerValueYaw")) * 1.27);
|
||||
}
|
||||
|
||||
m_aircraft->mrStatusLabel->setText(tr("Configuration OK"));
|
||||
@ -1046,7 +1029,9 @@ bool ConfigMultiRotorWidget::setupMultiRotorMixer(double mixerFactors[8][3])
|
||||
|
||||
setMixerValue(mixer, "MixerValueRoll", m_aircraft->mrRollMixLevel->value());
|
||||
setMixerValue(mixer, "MixerValuePitch", m_aircraft->mrPitchMixLevel->value());
|
||||
setMixerValue(mixer, "MixerValueYaw", m_aircraft->mrYawMixLevel->value());
|
||||
|
||||
// Store negative value if ReverseAllMotors is checked
|
||||
setMixerValue(mixer, "MixerValueYaw", m_aircraft->mrYawMixLevel->value() * (invertMotors ? -1.0 : 1.0));
|
||||
|
||||
QList<QComboBox *> mmList;
|
||||
mmList << m_aircraft->multiMotorChannelBox1 << m_aircraft->multiMotorChannelBox2
|
||||
|
@ -343,7 +343,7 @@ public:
|
||||
{
|
||||
QLineEdit *lineEdit = new QLineEdit(parent);
|
||||
|
||||
lineEdit->setInputMask(QString(maxLength(), 'H'));
|
||||
lineEdit->setInputMask(QString(TreeItem::maxHexStringLength(m_field->getType()), 'H'));
|
||||
|
||||
return lineEdit;
|
||||
}
|
||||
@ -401,36 +401,77 @@ private:
|
||||
|
||||
return str.toString().toUInt(&ok, 16);
|
||||
}
|
||||
};
|
||||
|
||||
int maxLength()
|
||||
class CharFieldTreeItem : public FieldTreeItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
CharFieldTreeItem(UAVObjectField *field, int index, const QList<QVariant> &data, TreeItem *parent = 0) :
|
||||
FieldTreeItem(index, data, parent), m_field(field)
|
||||
{}
|
||||
|
||||
CharFieldTreeItem(UAVObjectField *field, int index, const QVariant &data, TreeItem *parent = 0) :
|
||||
FieldTreeItem(index, data, parent), m_field(field)
|
||||
{}
|
||||
|
||||
QWidget *createEditor(QWidget *parent)
|
||||
{
|
||||
int maxLength = 0;
|
||||
QLineEdit *lineEdit = new QLineEdit(parent);
|
||||
|
||||
switch (m_field->getType()) {
|
||||
case UAVObjectField::INT8:
|
||||
maxLength = 2;
|
||||
break;
|
||||
case UAVObjectField::INT16:
|
||||
maxLength = 4;
|
||||
break;
|
||||
case UAVObjectField::INT32:
|
||||
maxLength = 8;
|
||||
break;
|
||||
case UAVObjectField::UINT8:
|
||||
maxLength = 2;
|
||||
break;
|
||||
case UAVObjectField::UINT16:
|
||||
maxLength = 4;
|
||||
break;
|
||||
case UAVObjectField::UINT32:
|
||||
maxLength = 8;
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
return maxLength;
|
||||
lineEdit->setInputMask(QString(1, 'N'));
|
||||
|
||||
return lineEdit;
|
||||
}
|
||||
|
||||
QVariant getEditorValue(QWidget *editor)
|
||||
{
|
||||
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
||||
|
||||
return lineEdit->text();
|
||||
}
|
||||
|
||||
void setEditorValue(QWidget *editor, QVariant value)
|
||||
{
|
||||
QLineEdit *lineEdit = static_cast<QLineEdit *>(editor);
|
||||
|
||||
lineEdit->setText(value.toString());
|
||||
}
|
||||
|
||||
void setData(QVariant value, int column)
|
||||
{
|
||||
setChanged(m_field->getValue(m_index) != toUInt(value));
|
||||
TreeItem::setData(value, column);
|
||||
}
|
||||
|
||||
void apply()
|
||||
{
|
||||
m_field->setValue(toUInt(data()), m_index);
|
||||
setChanged(false);
|
||||
}
|
||||
|
||||
void update()
|
||||
{
|
||||
QVariant value = toChar(m_field->getValue(m_index));
|
||||
|
||||
if (data() != value || changed()) {
|
||||
TreeItem::setData(value);
|
||||
setHighlight(true);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
UAVObjectField *m_field;
|
||||
|
||||
QVariant toChar(QVariant value)
|
||||
{
|
||||
return value.toChar();
|
||||
}
|
||||
|
||||
QVariant toUInt(QVariant str)
|
||||
{
|
||||
return QVariant(str.toString().at(0).toLatin1());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // FIELDTREEITEM_H
|
||||
|
@ -228,3 +228,34 @@ QList<MetaObjectTreeItem *> TopTreeItem::getMetaObjectItems()
|
||||
{
|
||||
return m_metaObjectTreeItemsPerObjectIds.values();
|
||||
}
|
||||
|
||||
QVariant ArrayFieldTreeItem::data(int column) const
|
||||
{
|
||||
if (column == 1) {
|
||||
if (m_field->getType() == UAVObjectField::UINT8 && m_field->getUnits().toLower() == "char") {
|
||||
QString dataString;
|
||||
for (uint i = 0; i < m_field->getNumElements(); ++i) {
|
||||
dataString.append(m_field->getValue(i).toChar());
|
||||
}
|
||||
QString data = QString("'%1'").arg(dataString);
|
||||
return data;
|
||||
} else if (m_field->getUnits().toLower() == "hex") {
|
||||
QString dataString;
|
||||
for (uint i = 0; i < m_field->getNumElements(); ++i) {
|
||||
if (i > 0) {
|
||||
dataString.append(' ');
|
||||
}
|
||||
bool ok;
|
||||
dataString.append(QString("%1")
|
||||
.arg(m_field->getValue(i).toUInt(&ok), TreeItem::maxHexStringLength(m_field->getType()),
|
||||
16, QChar('0')).toUpper());
|
||||
}
|
||||
QString data = QString("{%1}").arg(dataString);
|
||||
return data;
|
||||
} else {
|
||||
return QVariant();
|
||||
}
|
||||
} else {
|
||||
return TreeItem::data(column);
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
}
|
||||
int childCount() const;
|
||||
int columnCount() const;
|
||||
QVariant data(int column = 1) const;
|
||||
virtual QVariant data(int column = 1) const;
|
||||
QString description()
|
||||
{
|
||||
return m_description;
|
||||
@ -179,6 +179,27 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int maxHexStringLength(UAVObjectField::FieldType type)
|
||||
{
|
||||
switch (type) {
|
||||
case UAVObjectField::INT8:
|
||||
return 2;
|
||||
case UAVObjectField::INT16:
|
||||
return 4;
|
||||
case UAVObjectField::INT32:
|
||||
return 8;
|
||||
case UAVObjectField::UINT8:
|
||||
return 2;
|
||||
case UAVObjectField::UINT16:
|
||||
return 4;
|
||||
case UAVObjectField::UINT32:
|
||||
return 8;
|
||||
default:
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
signals:
|
||||
void updateHighlight(TreeItem *);
|
||||
|
||||
@ -324,8 +345,14 @@ public:
|
||||
class ArrayFieldTreeItem : public TreeItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ArrayFieldTreeItem(const QList<QVariant> &data, TreeItem *parent = 0) : TreeItem(data, parent) {}
|
||||
ArrayFieldTreeItem(const QVariant &data, TreeItem *parent = 0) : TreeItem(data, parent) {}
|
||||
ArrayFieldTreeItem(UAVObjectField *field, const QList<QVariant> &data, TreeItem *parent = 0) : TreeItem(data, parent), m_field(field)
|
||||
{}
|
||||
ArrayFieldTreeItem(UAVObjectField *field, const QVariant &data, TreeItem *parent = 0) : TreeItem(data, parent), m_field(field)
|
||||
{}
|
||||
QVariant data(int column) const;
|
||||
|
||||
private:
|
||||
UAVObjectField*m_field;
|
||||
};
|
||||
|
||||
#endif // TREEITEM_H
|
||||
|
@ -188,7 +188,7 @@ void UAVObjectTreeModel::addInstance(UAVObject *obj, TreeItem *parent)
|
||||
|
||||
void UAVObjectTreeModel::addArrayField(UAVObjectField *field, TreeItem *parent)
|
||||
{
|
||||
TreeItem *item = new ArrayFieldTreeItem(field->getName());
|
||||
TreeItem *item = new ArrayFieldTreeItem(field, field->getName());
|
||||
|
||||
item->setHighlightManager(m_highlightManager);
|
||||
connect(item, SIGNAL(updateHighlight(TreeItem *)), this, SLOT(updateHighlight(TreeItem *)));
|
||||
@ -230,6 +230,8 @@ void UAVObjectTreeModel::addSingleField(int index, UAVObjectField *field, TreeIt
|
||||
data.append(field->getUnits());
|
||||
if (field->getUnits().toLower() == "hex") {
|
||||
item = new HexFieldTreeItem(field, index, data);
|
||||
} else if (field->getUnits().toLower() == "char") {
|
||||
item = new CharFieldTreeItem(field, index, data);
|
||||
} else {
|
||||
item = new IntFieldTreeItem(field, index, data);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<description>Queries board for SN, model, revision, and sends reset command</description>
|
||||
<field name="Command" units="" type="uint16" elements="1"/>
|
||||
<field name="Description" units="" type="uint8" elements="100"/>
|
||||
<field name="CPUSerial" units="" type="uint8" elements="12" />
|
||||
<field name="CPUSerial" units="hex" type="uint8" elements="12" />
|
||||
<field name="BoardRevision" units="" type="uint16" elements="1"/>
|
||||
<field name="BoardType" units="" type="uint8" elements="1"/>
|
||||
<field name="BootloaderRevision" units="" type="uint8" elements="1"/>
|
||||
|
@ -3,9 +3,9 @@
|
||||
<description>Extended GPS status.</description>
|
||||
<field name="Status" units="" type="enum" elements="1" options="NONE,GPSV9" defaultvalue="NONE"/>
|
||||
<field name="FlightTime" units="" type="uint32" elements="1"/>
|
||||
<field name="BoardType" units="bytes" type="uint8" elements="2"/>
|
||||
<field name="FirmwareHash" units=" bytes" type="uint8" elements="8"/>
|
||||
<field name="FirmwareTag" units="bytes" type="uint8" elements="26"/>
|
||||
<field name="BoardType" units="hex" type="uint8" elements="2"/>
|
||||
<field name="FirmwareHash" units="hex" type="uint8" elements="8"/>
|
||||
<field name="FirmwareTag" units="char" type="uint8" elements="26"/>
|
||||
<field name="Options" units="" type="uint16" elements="1"/>
|
||||
<access gcs="readwrite" flight="readwrite"/>
|
||||
<telemetrygcs acked="false" updatemode="manual" period="0"/>
|
||||
|
Loading…
Reference in New Issue
Block a user