1
0
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:
m_thread 2014-10-08 00:56:24 +02:00
commit b794c87d3b
9 changed files with 168 additions and 79 deletions

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}

View File

@ -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"/>

View File

@ -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"/>