Skip to content

Commit 6afe8cf

Browse files
iakovzhitmMinyazevR
authored
Add basic NXT suport for GNU/Linux (#1900)
Initial Lego NXT support for GNU/Linux desktops. Requires downloading or installing from repo of a corresponding cross-compiler for obsolete ARMv5 ISA. * Add RXE compilation on Linux for NXT * Minor fixes with code improvements * Disable generatorSettingsGroupBox for Windows * Fix typo in control UI file --------- Co-authored-by: zhitm <zhtinuhina.maria@gmail.com> Co-authored-by: MinyazevR <eeuriset8@gmail.com>
1 parent 8a4cf6b commit 6afe8cf

File tree

14 files changed

+221
-79
lines changed

14 files changed

+221
-79
lines changed

.gitmodules

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
url = https://bitbucket.org/codeimproved/qslog.git
2626
[submodule "installer/nxt-tools"]
2727
path = installer/nxt-tools
28-
url = https://github.com/trikset/nxt-tools
28+
url = https://github.com/trikset/nxt-tools.git
29+
branch = main
2930
[submodule "trik-checkapp"]
3031
path = thirdparty/checkapp/checkapp
3132
url = https://github.com/trikset/trik-checkapp

installer/nxt-tools

Submodule nxt-tools updated 4377 files

installer/packages/trik-studio/ru.qreal.root.nxt.tools/meta/prebuild-linux-gnu.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ cd "$(dirname "$0")"
66
source "$INSTALLER_ROOT"/utils/common_utils.sh
77
mkdir "$PWD"/../data/bin
88
cd "$PWD"/../data/bin
9-
rsync -a "$INSTALLER_ROOT"/nxt-tools/linux/nxt-tools ./
9+
rsync -a "$INSTALLER_ROOT"/nxt-tools ./

installer/packages/trik-studio/ru.qreal.root.nxt.tools/meta/prebuild-win32.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ source "$INSTALLER_ROOT"/utils/common_utils.sh
77

88
cd "$PWD"/../data
99

10-
rsync -aR "$INSTALLER_ROOT"/nxt-tools/win/./nxt-tools .
10+
rsync -aR "$INSTALLER_ROOT"/./nxt-tools .
1111
dos2unix nxt-tools/compile.sh
1212
rm -rf bin

plugins/robots/generators/nxt/nxtOsekCGenerator/nxtFlashTool.cpp

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,25 @@ bool NxtFlashTool::uploadProgram(const QFileInfo &fileInfo)
222222
mCompileState = idle;
223223
mSource = fileInfo;
224224

225-
#ifdef Q_OS_WIN
226225
mCompileProcess.setWorkingDirectory(path());
227-
mCompileProcess.start("cmd", { "/c", path("compile.bat")
228-
+ " " + fileInfo.completeBaseName()
229-
+ " " + fileInfo.absolutePath() });
230-
#else
231-
mCompileProcess.start("sh", { path("compile.sh") , fileInfo.absolutePath()});
232-
#endif
233226

227+
auto osType = PlatformInfo::osType();
228+
if (osType == "windows") {
229+
auto line = path("compile.bat")
230+
+ " " + fileInfo.completeBaseName()
231+
+ " " + fileInfo.absolutePath()
232+
+ " " + path("gnuarm");
233+
mCompileProcess.start("cmd", { "/c", line});
234+
}
235+
else if (osType == "linux") {
236+
auto line = "./compile.sh . " + fileInfo.absolutePath() +
237+
" GNUARM_ROOT="+SettingsManager::value("pathToArmNoneEabi").toString();
238+
mCompileProcess.start("/bin/bash", {"-c", line});
239+
}
240+
else {
241+
QLOG_INFO() << "Platform: " << osType << "not supported for upload program";
242+
return false;
243+
}
234244
information(tr("Uploading program started. Please don't disconnect robot during the process"));
235245
return true;
236246
}
@@ -291,6 +301,10 @@ void NxtFlashTool::readNxtCompileData()
291301
"If you sure in their validness contact developers"));
292302
} else {
293303
error(tr("Could not upload program. Make sure the robot is connected and ON"));
304+
if (PlatformInfo::osType() == "linux") {
305+
error(tr("If you are using GNU/Linux visit "
306+
"https://help.trikset.com/nxt/run-upload-programs to get instructions"));
307+
}
294308
}
295309
}
296310

plugins/robots/generators/nxt/nxtOsekCGenerator/nxtOsekCGeneratorPlugin.cpp

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
* limitations under the License. */
1414

1515
#include "nxtOsekCGeneratorPlugin.h"
16-
1716
#include <QtCore/QDir>
1817
#include <QtCore/QDateTime>
1918
#include <QtWidgets/QApplication>
@@ -22,6 +21,7 @@
2221
#include <qrkernel/platformInfo.h>
2322
#include <qrutils/singleton.h>
2423

24+
#include "QsLog.h"
2525
#include "nxtOsekCMasterGenerator.h"
2626

2727
using namespace nxt::osekC;
@@ -36,6 +36,12 @@ NxtOsekCGeneratorPlugin::NxtOsekCGeneratorPlugin()
3636
, mNxtToolsPresent(false)
3737
, mCommunicator(utils::Singleton<communication::UsbRobotCommunicationThread>::instance())
3838
{
39+
const QString key = "pathToArmNoneEabi";
40+
const QString defaultPath = QDir(PlatformInfo::invariantSettingsPath("pathToNxtTools")).absolutePath()
41+
+"/arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-eabi";
42+
if (qReal::SettingsManager::value(key).isNull()) {
43+
qReal::SettingsManager::setValue(key, defaultPath);
44+
}
3945
initActions();
4046
initHotKeyActions();
4147
}
@@ -95,7 +101,6 @@ void NxtOsekCGeneratorPlugin::onCurrentDiagramChanged(const TabInfo &info)
95101
void NxtOsekCGeneratorPlugin::init(const kitBase::KitPluginConfigurator &configurator)
96102
{
97103
RobotsGeneratorPluginBase::init(configurator);
98-
99104
mFlashTool.reset(new NxtFlashTool(*mMainWindowInterface->errorReporter(), *mCommunicator));
100105
connect(&*mFlashTool, &NxtFlashTool::uploadingComplete, this, &NxtOsekCGeneratorPlugin::onUploadingComplete);
101106
}
@@ -225,21 +230,27 @@ void NxtOsekCGeneratorPlugin::uploadProgram()
225230
void NxtOsekCGeneratorPlugin::checkNxtTools()
226231
{
227232
const QDir dir(PlatformInfo::invariantSettingsPath("pathToNxtTools"));
228-
if (!dir.exists()) {
229-
mNxtToolsPresent = false;
230-
} else {
231-
QDir gnuarm(dir.absolutePath() + "/gnuarm/bin");
232-
QDir nexttool(dir.absolutePath() + "/nexttool");
233-
QDir nxtOSEK(dir.absolutePath() + "/nxtOSEK");
234-
235-
#ifdef Q_OS_WIN
236-
QFile compile1(dir.absolutePath() + "/compile.bat");
237-
QFile compile2(dir.absolutePath() + "/compile.sh");
238-
mNxtToolsPresent = gnuarm.exists() && nexttool.exists() && nxtOSEK.exists()
239-
&& compile1.exists() && compile2.exists();
240-
#else
241-
QFile compile(dir.absolutePath() + "/compile.sh");
242-
mNxtToolsPresent = gnuarm.exists() && nexttool.exists() && nxtOSEK.exists() && compile.exists();
243-
#endif
233+
auto compilePath = dir.absolutePath() + "/compile.sh";
234+
235+
auto nxtToolsPresent = dir.exists()
236+
&& QFileInfo::exists(dir.absolutePath() + "/gnuarm")
237+
&& QFileInfo::exists(dir.absolutePath() + "/nexttool")
238+
&& QFileInfo::exists(dir.absolutePath() + "/nxtOSEK")
239+
&& QFileInfo::exists(compilePath) && QFileInfo(compilePath).isFile();
240+
241+
if (!nxtToolsPresent) {
242+
mNxtToolsPresent = false;
243+
QLOG_ERROR() << "Missing" << dir.absolutePath() << "or mandatory subdirectory" <<
244+
dir.entryList(QDir::Filter::NoFilter, QDir::SortFlag::DirsFirst | QDir::SortFlag::Name);
245+
return;
246+
}
247+
248+
auto osType = PlatformInfo::osType();
249+
if (osType == "linux") {
250+
mNxtToolsPresent = true;
251+
}
252+
else if (osType == "windows") {
253+
auto compileBatPath = dir.absolutePath() + "/compile.bat";
254+
mNxtToolsPresent = QFileInfo::exists(compileBatPath) && QFileInfo(compileBatPath).isFile();
244255
}
245256
}

plugins/robots/interpreters/nxtKitInterpreter/src/nxtAdditionalPreferences.cpp

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414

1515
#include "nxtAdditionalPreferences.h"
1616
#include "ui_nxtAdditionalPreferences.h"
17-
1817
#include <qrkernel/settingsManager.h>
1918
#include <utils/widgets/comPortPicker.h>
19+
#include "QsLog.h"
20+
#include <QOperatingSystemVersion>
21+
#include <qrkernel/platformInfo.h>
2022

2123
using namespace nxt;
2224
using namespace qReal;
@@ -28,6 +30,13 @@ NxtAdditionalPreferences::NxtAdditionalPreferences(const QString &realRobotName,
2830
{
2931
mUi->setupUi(this);
3032
mUi->robotImagePicker->configure("nxtRobot2DImage", tr("2D robot image:"));
33+
if (PlatformInfo::osType() == "linux") {
34+
mUi->compilerPicker->configure("pathToArmNoneEabi", tr("Path to arm-none-eabi:"));
35+
setTextOnGeneratorLabel();
36+
}
37+
else {
38+
mUi->generatorSettingsGroupBox->setVisible(false);
39+
}
3140
connect(mUi->manualComPortCheckbox, &QCheckBox::toggled
3241
, this, &NxtAdditionalPreferences::manualComPortCheckboxChecked);
3342
}
@@ -37,18 +46,44 @@ NxtAdditionalPreferences::~NxtAdditionalPreferences()
3746
delete mUi;
3847
}
3948

49+
void NxtAdditionalPreferences::setColorOnGeneratorLabel(QColor color){
50+
QPalette palette = mUi->generatorLabel->palette();
51+
palette.setColor(mUi->generatorLabel->foregroundRole(), color);
52+
mUi->generatorLabel->setPalette(palette);
53+
}
54+
55+
void NxtAdditionalPreferences::setTextOnGeneratorLabel(){
56+
if (!mUi->compilerPicker->isSavedDirExist()){
57+
mUi->generatorLabel->setText(tr("WARNING: Current directory doesn't exist. \nOpen "
58+
"<a href=\"https://help.trikset.com/nxt/run-upload-programs\">link</a>"
59+
" for instructions"));
60+
mUi->generatorLabel->setTextFormat(Qt::RichText);
61+
mUi->generatorLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
62+
mUi->generatorLabel->setOpenExternalLinks(true);
63+
setColorOnGeneratorLabel(QColor("red"));
64+
}
65+
else {
66+
mUi->generatorLabel->setText("Current directory exist.");
67+
setColorOnGeneratorLabel(QColor("black"));
68+
}
69+
}
70+
4071
void NxtAdditionalPreferences::save()
4172
{
4273
SettingsManager::setValue("NxtBluetoothPortName", selectedPortName());
4374
SettingsManager::setValue("NxtManualComPortCheckboxChecked", mUi->manualComPortCheckbox->isChecked());
4475
mUi->robotImagePicker->save();
76+
mUi->compilerPicker->save();
77+
setTextOnGeneratorLabel();
4578
emit settingsChanged();
4679
}
4780

4881
void NxtAdditionalPreferences::restoreSettings()
4982
{
5083
ui::ComPortPicker::populate(*mUi->comPortComboBox, "NxtBluetoothPortName");
5184
mUi->robotImagePicker->restore();
85+
mUi->compilerPicker->restore();
86+
setTextOnGeneratorLabel();
5287

5388
if (mUi->comPortComboBox->count() == 0) {
5489
mUi->comPortComboBox->hide();
@@ -72,7 +107,11 @@ void NxtAdditionalPreferences::restoreSettings()
72107

73108
void NxtAdditionalPreferences::onRobotModelChanged(kitBase::robotModel::RobotModelInterface * const robotModel)
74109
{
110+
QLOG_DEBUG() << robotModel->name();
75111
mUi->bluetoothSettingsGroupBox->setVisible(robotModel->name() == mBluetoothRobotName);
112+
if (PlatformInfo::osType() == "linux") {
113+
mUi->generatorSettingsGroupBox->setVisible(robotModel->name() == "NxtOsekCGeneratorRobotModel");
114+
}
76115
}
77116

78117
void NxtAdditionalPreferences::manualComPortCheckboxChecked(bool state)

plugins/robots/interpreters/nxtKitInterpreter/src/nxtAdditionalPreferences.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ private slots:
4242

4343
private:
4444
QString selectedPortName() const;
45-
45+
void setColorOnGeneratorLabel(QColor color);
46+
void setTextOnGeneratorLabel();
4647
Ui::NxtAdditionalPreferences *mUi;
4748
const QString mBluetoothRobotName;
4849
};

plugins/robots/interpreters/nxtKitInterpreter/src/nxtAdditionalPreferences.ui

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>414</width>
10-
<height>164</height>
9+
<width>401</width>
10+
<height>284</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -27,22 +27,33 @@
2727
<number>0</number>
2828
</property>
2929
<item>
30-
<widget class="qReal::ui::ImagePicker" name="robotImagePicker">
31-
</widget>
30+
<widget class="qReal::ui::ImagePicker" name="robotImagePicker" native="true"/>
3231
</item>
3332
<item>
34-
<widget class="QGroupBox" name="bluetoothSettingsGroupBox">
33+
<widget class="QGroupBox" name="generatorSettingsGroupBox">
3534
<property name="title">
36-
<string>Bluetooth Settings</string>
35+
<string>nxtOSEK Generator Settings</string>
3736
</property>
38-
<layout class="QGridLayout" name="gridLayout_4">
37+
<layout class="QGridLayout" name="gridLayout">
3938
<item row="1" column="0">
40-
<widget class="QLabel" name="comPortLabel">
39+
<widget class="QLabel" name="generatorLabel">
4140
<property name="text">
42-
<string>COM Port:</string>
41+
<string>TextLabel</string>
4342
</property>
4443
</widget>
4544
</item>
45+
<item row="0" column="0">
46+
<widget class="qReal::ui::DirPicker" name="compilerPicker" native="true"/>
47+
</item>
48+
</layout>
49+
</widget>
50+
</item>
51+
<item>
52+
<widget class="QGroupBox" name="bluetoothSettingsGroupBox">
53+
<property name="title">
54+
<string>Bluetooth Settings</string>
55+
</property>
56+
<layout class="QGridLayout" name="gridLayout_4">
4657
<item row="1" column="1">
4758
<widget class="QComboBox" name="comPortComboBox">
4859
<property name="sizePolicy">
@@ -53,16 +64,6 @@
5364
</property>
5465
</widget>
5566
</item>
56-
<item row="2" column="0">
57-
<widget class="QLabel" name="directInputComPortLabel">
58-
<property name="text">
59-
<string>COM Port:</string>
60-
</property>
61-
</widget>
62-
</item>
63-
<item row="2" column="1">
64-
<widget class="QLineEdit" name="directInputComPortLineEdit"/>
65-
</item>
6667
<item row="0" column="0" colspan="2">
6768
<widget class="QLabel" name="noComPortsFoundLabel">
6869
<property name="text">
@@ -73,13 +74,30 @@
7374
</property>
7475
</widget>
7576
</item>
77+
<item row="2" column="1">
78+
<widget class="QLineEdit" name="directInputComPortLineEdit"/>
79+
</item>
7680
<item row="3" column="0" colspan="2">
7781
<widget class="QCheckBox" name="manualComPortCheckbox">
7882
<property name="text">
7983
<string>Specify COM port manually</string>
8084
</property>
8185
</widget>
8286
</item>
87+
<item row="1" column="0">
88+
<widget class="QLabel" name="comPortLabel">
89+
<property name="text">
90+
<string>COM Port:</string>
91+
</property>
92+
</widget>
93+
</item>
94+
<item row="2" column="0">
95+
<widget class="QLabel" name="directInputComPortLabel">
96+
<property name="text">
97+
<string>COM Port:</string>
98+
</property>
99+
</widget>
100+
</item>
83101
</layout>
84102
</widget>
85103
</item>
@@ -92,6 +110,12 @@
92110
<header>qrutils/widgets/imagePicker.h</header>
93111
<container>1</container>
94112
</customwidget>
113+
<customwidget>
114+
<class>qReal::ui::DirPicker</class>
115+
<extends>QWidget</extends>
116+
<header>qrutils/widgets/dirPicker.h</header>
117+
<container>1</container>
118+
</customwidget>
95119
</customwidgets>
96120
<resources/>
97121
<connections/>

0 commit comments

Comments
 (0)