Compare commits

...

24 Commits
v0.8 ... v0.8.1

Author SHA1 Message Date
Oleg Kalachev
3b0dd46ca6 Decrease conn/timeout to 8 seconds 2018-07-25 15:40:38 +03:00
Oleg Kalachev
16b2e1903a Fix udp and udp-b bridge settings 2018-07-25 15:40:38 +03:00
Smirnov Artem
36d7a95d34 Merge pull request #58 from urpylka/rm_mount_point
image_builder: fix pack 4
2018-07-25 14:33:11 +04:00
Artem Smirnov
1d82e195ec image_builder: add checkout to GWBT_REF 2018-07-25 12:55:18 +03:00
Artem Smirnov
78cae0c69a image_builder: fix vars syntax 2018-07-25 12:55:18 +03:00
Oleg Kalachev
2b46ee27f2 docs: small fix 2018-07-25 12:26:43 +03:00
Oleg Kalachev
de44400749 Merge branch 'master' of github.com:CopterExpress/clever 2018-07-25 12:01:47 +03:00
Oleg Kalachev
55e40bd6c3 docs: add mobile rc page [wip] 2018-07-25 12:01:38 +03:00
Artem Smirnov
124950d7e4 image_builder: remove MOUNT_POINT
I changed CONST-PATH to dynamic dir by mktemp
2018-07-24 19:05:04 +03:00
Smirnov Artem
199104ca83 Merge pull request #57 from urpylka/master
image_builder: fix pack
2018-07-24 16:33:19 +04:00
Artem Smirnov
e5552e0a4b image_builder: replace old archive 2018-07-24 15:16:56 +03:00
Oleg Kalachev
bfb0aa7961 Force gitbook update 2018-07-16 23:34:00 +03:00
Smirnov Artem
44d83bdcf8 Merge pull request #56 from Yuliya1404/master
added description of project and links to telegtam chats
2018-07-11 22:41:12 +03:00
Yuliya1404
d960e57cf9 docs: small fix 2018-07-11 15:47:38 +03:00
Yuliya1404
30ec03ef4d docs: added description of project and links on telegram chat 2018-07-11 15:28:34 +03:00
Smirnov Artem
c2c27b1577 docs: added build status icon 2018-07-08 15:09:51 +03:00
Oleg Kalachev
c0449ccf59 docs update 2018-07-07 17:58:33 +03:00
Oleg Kalachev
ea933ce3d1 docs: small fix 2018-07-07 17:57:02 +03:00
Oleg Kalachev
327666385b docs: small fix 2018-07-07 17:55:54 +03:00
Oleg Kalachev
8ea511b293 docs: firmware.md fixes 2018-07-07 17:54:09 +03:00
Oleg Kalachev
c510fe5cf0 Merge branch 'master' of github.com:CopterExpress/clever 2018-07-07 17:50:47 +03:00
Oleg Kalachev
dab70937f5 docs: add article about px4 firmware uploading 2018-07-07 17:50:42 +03:00
Artem Smirnov
204dd97b00 image_builder: remove date from image name 2018-06-26 19:49:42 +03:00
Artem Smirnov
27bfecc737 image_builder: add information about new partitions 2018-06-25 19:33:11 +03:00
24 changed files with 264 additions and 114 deletions

View File

@@ -14,6 +14,8 @@ Use it to learn how to assemble, configure, pilot and program autonomous CLEVER
**Preconfigured image for Raspberry Pi 3 with installed and configured software, ready to fly, is available [in the Releases section](https://github.com/CopterExpress/clever/releases).**
[![Build Status](http://builder.coex.space/job/CopterExpress---clever/badge/icon)](http://builder.coex.space/job/CopterExpress---clever/)
Image includes:
* Raspbian Stretch

View File

@@ -18,11 +18,11 @@
<!-- gcs bridge -->
<param name="gcs_url" value="tcp-l://0.0.0.0:5760" if="$(eval gcs_bridge == 'tcp')"/>
<param name="gcs_url" value="udp://0.0.0.0:14550@14550" if="$(eval gcs_bridge == 'udp')"/>
<param name="gcs_url" value="udp-b://0.0.0.0:14550@14550" if="$(eval gcs_bridge == 'udp-b')"/>
<param name="gcs_url" value="udp-pb://0.0.0.0:14550@14550" if="$(eval gcs_bridge == 'udp-pb')"/>
<param name="gcs_url" value="udp-b://$(env ROS_IP):14550@14550" if="$(eval gcs_bridge == 'udp-b')"/>
<param name="gcs_url" value="udp-pb://$(env ROS_IP):14550@14550" if="$(eval gcs_bridge == 'udp-pb')"/>
<param name="gcs_url" value="" if="$(eval not gcs_bridge)"/>
<param name="gcs_quiet_mode" value="true"/>
<param name="conn/timeout" value="10"/>
<param name="conn/timeout" value="8"/>
<!-- default px4 params -->
<rosparam command="load" file="$(find mavros)/launch/px4_config.yaml"/>

View File

@@ -11,6 +11,10 @@
Для того, чтобы научиться собирать, настраивать, пилотировать и программировать автономный дрон «Клевер», воспользуйтесь этим учебником.
Если вы детально изучили наш gitbook, но так и не нашли ответа на свой вопрос, напишите в чат техподдержки и наши специалисты вам с радостью ответят https://t.me/COEXHelpdesk .
Также, у нас есть чат для программистов, которые разрабатывают под PX4, автономную навигацию в помещениях и рои дронов https://t.me/DroneCode .
Образ для Raspberry Pi
----------------------

View File

@@ -9,6 +9,8 @@
* [Подключение Raspberry Pi к PixHawk](connection.md)
* [Подключение по Wi-Fi](wifi.md)
* [Работа с QGroundControl через Wi-Fi](gcs_bridge.md)
* [Прошивка PixHawk/PixRacer](firmware.md)
* [Пилотирование со смартфона](rc.md)
* [SSH-доступ](ssh.md)
* [Неисправности радиоаппаратуры](radioerrors.md)
* [Безопасность](safety.md)
@@ -38,4 +40,5 @@
* [CopterHack-2017](copterhack2017.md)
* [Прошивка ESC контроллеров с помощью Arduino](esc_firmware.md)
* [Работа со светодиодной лентой](leds.md)
* [Проекты на базе коптера "Клевер"](projects.md)
* [Полезные ссылки](links.md)

BIN
docs/assets/3dmodel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
docs/assets/ball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

BIN
docs/assets/calculation.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
docs/assets/detal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 KiB

BIN
docs/assets/detal1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 KiB

BIN
docs/assets/detal2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 KiB

BIN
docs/assets/elements.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

BIN
docs/assets/elements1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

BIN
docs/assets/finalball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 KiB

BIN
docs/assets/safetyball.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

BIN
docs/assets/stmrev.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
docs/assets/table.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -0,0 +1,53 @@
Прошивка PixHawk / PixRacer
===
PixHawk или PixRacer можно прошить, используя QGroundControl или утилиты командной строки.
Различные варианты сборок стабильных прошивок PX4 можно скачать в разделе [Releases на GitHub](https://github.com/PX4/Firmware/releases).
В названии файла прошивки кодируется информации о целевой плате и варианте сборки. Примеры:
* `px4fmu-v2_default.px4` — прошивка для PixHawk с EKF2.
* `px4fmu-v2_lpe.px4` — прошивка для PixHawk с LPE.
* `px4fmu-v4_default.px4` — прошивка для PixRacer с EKF2 и LPE (*Клевер 3*).
* `px4fmu-v3_default.px4` — прошивка для более новых версий PixHawk (чип ревизии 3, см. илл. + Bootloader v5) с EKF2 и LPE.
![](assets/stmrev.jpg)
> **Note** Для загрузки `px4fmu-v3_default.px4` может понадобиться использование команды `force_upload` из командной строки.
QGroundControl
---
В QGroundControl откройте раздел Firmware. **После** этого подключите PixHawk / PixRacer по USB.
Выберите PX4 Flight Stack. Для скачивания и загрузки стандартной прошивки (вариант с EKF2 для PixHawk) выберите пункт меню "Standard Version", для загрузки собственного файла прошивки выберите пункт "Custom firmware file...", затем нажмите OK.
> **Warning** Не отключайте USB-кабель до окончания процесса прошивки.
TODO: Иллюстрация.
Командная строка
---
PX4 может быть собран из исходников и загружен в плату автоматически из командной строки.
Для это склонируйте репозиторий PX4:
```bash
git clone https://github.com/PX4/Firmware.git
```
Выберите необходимую версию (тэг) с помощью `git checkout`. Затем соберите и загрузите прошивку:
```
make px4fmu-v4_default upload
```
Где `px4fmu-v4_default` – требуемый вариант прошивки.
Для загрузки прошивки `v3` в PixHawk может понадобиться команда `force_upload`:
```
make px4fmu-v3_default force-upload
```

94
docs/projects.md Normal file
View File

@@ -0,0 +1,94 @@
# Шаровая защита коптера
1. Введение
Наверное, летать в помещениях приходилось каждому, кто брал в руки коптер. Подобные полеты сопряжены с немалым риском повредить коптер о стены и различные предметы. Даже полеты на относительно больших пространствах связаны с рисками удариться о препятствие: на пути коптера может встать ствол дерева или здание — что уж говорить о полетах в замкнутых пространствах. Подобные «краш-тесты» не очень приятный момент, который может оказаться в лучшем случае причиной потери внушительной суммы денег на ремонт, а в худшем — и вовсе утраты коптера. Тем более неприятны такие ситуации для новичка, который не может своевременно увернуться от препятствия и только учится летать.
Это все подвигло нас к поиску решений. К сожалению, перерыв весь интернет, мы не нашли достаточно легкого и простого в изготовлении решения для простых пользователей, а главное — такого, которое будет всем по карману. Например, защита по контуру пропеллеров неплохо предохраняет сами пропеллеры, но при малейшем касании о препятствие коптер переворачивается и падает. В общем, защита либо не оберегала коптер полностью, либо выглядела несуразно и была слишком узко доступна.
![safetyball](assets/safetyball.png)
Нами было принято сложное решение: придется делать ее полностью самим и почти с нуля, а также поставлена цель сделать ее простой в изготовлении и максимально легкой.
2. Разработка
В результате поиска решения, удовлетворяющего всем нашим требованиям, мы остановились на нескольких схожих вариантах. Было решено сделать защиту в форме полуправильного многогранника (примерами могут служить фуллерен, молекула углерода, или фигура пентакисдодекаэдр) — его мы и выбрали как самый приятный глазу. Кроме того, такая защита легко масштабируема под нужный размер.
При создании такой фигуры используются два вида ребер (далее — лучей): короткие и длинные, их длины рассчитываются исходя из нужного диаметра вписанной в многогранник сферы. Для лучшего понимания я вставлю все необходимые формулы ниже из «Википедии».
![calculation](assets/calculation.png)
С угловыми соединениями (фитингами), тоже не все просто: их также два вида — с пятью гранями при вершине (пять лучей исходят из вершины) и с шестью гранями (шесть лучей исходят из вершины).
3. Первые модели
Была составлена спецификация для удобства контроля процесса изготовления, и мы приступили к моделированию.
Сделав несложные расчеты под нужные размеры, мы построили модели в Inventor CAD.
В ходе проектирования мы столкнулись с проблемами в моделировании угловых соединений, но они были решены упрощением конструкции, а разность углов компенсируется гибкостью материалов. Таким образом, все соединения сидят в небольшом натяге.
![table](assets/table.png)
![elements](assets/elements.png)
(Элементы крепления защиты к корпусу)
![elements1](assets/elements1.png)
4. Материалы
В ходе проектирования встал вопрос, из чего же все-таки сделать такую защиту, чтобы получилось легко и прочно. Ответ пришел, как всегда, совершенно неожиданно. На глаза попались шпажки из бамбука: они достаточно тонкие, чтобы не повлиять на аэродинамику, имеют достаточную гибкость и при этом достаточно прочные. Далее возник вопрос, из чего и как делать фитинги. Конечно же, 3D-печать! 3D-принтер — это вообще незаменимая вещь, тем более для тех, кто любит что-то делать сам. К тому же они из-за не самой высокой цены получили достаточно широкое распространение. На таком принтере можно делать изделия почти любой сложности. То, что надо!
Готовые модели переводим в .stl, закидываем в слайсер (в нашем случае — Cura), вводим настройки под конкретный принтер и пластик и ставим на печать.
Для уменьшения веса был выбран ABC-пластик как один из самых легких и доступных.
![3dmodel](assets/3dmodel.png)
Шпажки были порезаны на расчетные длины и подготовлены к последующей работе.
5. Сборка и установка
После того как все было напечатано и порезано, настало время собирать защиту.
![detal](assets/detal.png)
Сборка здесь самый ответственный момент, так как требует специального алгоритма.
Из пятилучевого фитинга выходят только короткие лучи, в то время как из шестилучевого — только каждая вторая длинная.
Сборка:
1. Вначале собираем все пятилучевые вершины.
2. На каждый луч, исходящий из пятилучевой вершины, надеваем шестилучевую.
3. Соединяем между собой шестилучевые фитинги длинными шпажками.
4. Присоединяем уже собранные пятилучевые вершины к шестилучевым, учитывая, что в шестилучевом фитинге короткие и длинные лучи чередуются.
5. Повторяем процесс для каждой пятилучевой вершины, пока шар не соберется.
После сборки разделяем шар на две полусферы, устанавливаем крепления на коптер, смотрим, что все подходит.
![detal1](assets/detal1.png)
![detal2](assets/detal2.png)
(Пример установки креплений)
Теперь полусферы можно проклеивать. Между собой полусферы не склеиваются — это нужно для установки коптера внутрь. Мы в качестве клея использовали растворитель для пластиков «Дихлорэтан», но с тем же успехом можно использовать и любой быстросохнущий клей для полимеров.
После высыхания защита готова к установке и первым пробным полетам!
![finalball](assets/finalball.png)
(Пока еще без креплений)
![ball](assets/ball.png)
6. Первые полеты
Мы делали защиту под коптер «Клевер 2», являющийся обучающим пособием по сборке и настройке квадрокоптеров, и на него она устанавливается без доработок. Защита весит на 70 г больше (139 грамм), чем стандартная, и на управляемость и время полета почти не влияет.
Отдельно стоит сказать, что излишние вибрации, если таковые имеются, можно убрать путем более жесткого крепления защиты к коптеру.
В итоге получилась необычная защита для коптера с небольшим весом и интересным дизайном, открывающая новые горизонты для полетов в тех местах, где летать для коптера раньше было опасно.

View File

@@ -1,13 +1,15 @@
Управление Клевером со смартфона
===
Для управления Клевером со смартфона через Wi-Fi необходимо установить приложение  [iOS](), Android (в разработке).
**WORK-IN-PROGRESS**
Для управления Клевером со смартфона через Wi-Fi необходимо установить приложение  iOS (TODO), Android (TODO).
![](assets/IMG_4397.PNG)
> **Warning** Мобильный пульт предназначен в первую очередь для полетов в помещении на дальность не более 10-15 м. Большое количество Wi-Fi сетей также может ухудшить отзывчивость и дальность пульта.
> **Info** Также управление со смартфона [доступно в мобильной версия приложения](https://docs.qgroundcontrol.com/en/SettingsView/VirtualJoystick.html) QGroundControl.
Также управление со смартфона [доступно в мобильной версия приложения](https://docs.qgroundcontrol.com/en/SettingsView/VirtualJoystick.html) QGroundControl.
Настройка
---

View File

@@ -4,7 +4,7 @@ pipeline {
string(name: 'GWBT_REF', defaultValue: "master")
string(name: 'GWBT_URL', defaultValue: "https://github.com/CopterExpress/clever.git")
string(name: 'GWBT_FILE', defaultValue: "")
string(name: 'IMAGE_NAME', defaultValue: "\$(cat ${GWBT_FILE} | jq '.repository.name' -r)_${params.GWBT_REF}_\$(cat ${GWBT_FILE} | jq '.release.published_at' -r).img")
string(name: 'IMAGE_NAME', defaultValue: "\$(cat ${GWBT_FILE} | jq '.repository.name' -r)-${params.GWBT_REF}.img")
string(name: 'GWBT_EVENT', defaultValue: 'release')
booleanParam(name: 'ONLY_PUBLISH', defaultValue: false, description: 'ONLY PUBLISH')
string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace')

View File

@@ -96,3 +96,8 @@ echo -e "\033[0;31m\033[1mSize of result image: $endresult (bytes)\033[0m\033[0m
echo "================================================================================"
truncate -s $endresult $strImgFile
echo "================================================================================"
partinfo=`parted -m $strImgFile unit B print`
echo -e "\033[0;31m\033[1mPartition information:\033[0m\033[0m\n$partinfo"
echo "================================================================================"

View File

@@ -6,7 +6,6 @@ pipeline {
string(name: 'IMAGE_VERSION', defaultValue: 'no_version', description: 'Image version')
string(name: 'BUILD_DIR', defaultValue: '/mnt/hdd_builder/workspace', description: 'Build workspace')
string(name: 'MOUNT_POINT', defaultValue: '/mnt/hdd_builder/image', description: 'Mount point')
string(name: 'RPI_DONWLOAD_URL', defaultValue: 'https://downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2017-12-01/2017-11-29-raspbian-stretch-lite.zip')
// TODO: Add mirrorparameters
@@ -42,7 +41,7 @@ pipeline {
}
// TODO: Transfer apps.sh initialisation code here
steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE ${params.IMAGE_VERSION} \$(basename ${params.RPI_DONWLOAD_URL})"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE ${params.IMAGE_VERSION} \$(basename ${params.RPI_DONWLOAD_URL})"
}
}
stage('Hardware setup') {
@@ -50,7 +49,7 @@ pipeline {
EXECUTE_FILE = 'image_builder/scripts/hardware_setup.sh'
}
steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
}
}
stage('Software install') {
@@ -58,7 +57,7 @@ pipeline {
EXECUTE_FILE = 'image_builder/scripts/software_install.sh'
}
steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
}
}
stage('Network setup') {
@@ -66,17 +65,18 @@ pipeline {
EXECUTE_FILE = 'image_builder/scripts/network_setup.sh'
}
steps {
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
}
}
stage('Install ROS') {
environment {
EXECUTE_FILE = 'image_builder/scripts/ros_install.sh'
MOVE_FILE = 'image_builder/kinetic-ros-coex.rosinstall'
MOVE_TO = '/home/pi/ros_catkin_ws'
}
steps {
sh "if ! ${params.DISCOVER_ROS_PACKAGES}; then $WORKSPACE/image_builder/image_config.sh copy_to_chroot ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$MOVE_FILE; fi"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE ${params.GWBT_URL} ${params.DISCOVER_ROS_PACKAGES}"
sh "if ! ${params.DISCOVER_ROS_PACKAGES}; then $WORKSPACE/image_builder/image_config.sh copy_to_chroot ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$MOVE_FILE $MOVE_TO; fi"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE ${params.GWBT_URL} ${params.GWBT_REF} ${params.DISCOVER_ROS_PACKAGES}"
}
}
// TODO: Add finalising step, transfer mirror removal from ros.sh
@@ -87,7 +87,7 @@ pipeline {
when { expression { return params.SHRINK } }
steps {
sh "$WORKSPACE/image_builder/autosizer.sh ${params.BUILD_DIR}/${params.IMAGE_NAME}"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} ${params.MOUNT_POINT} $WORKSPACE/$EXECUTE_FILE"
sh "$WORKSPACE/image_builder/image_config.sh execute ${params.BUILD_DIR}/${params.IMAGE_NAME} $WORKSPACE/$EXECUTE_FILE"
}
}
}

View File

@@ -15,17 +15,17 @@ get_image() {
# TEMPLATE: get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME
local RPI_ZIP_NAME=$(basename $2)
if [ ! -e "$1/$RPI_ZIP_NAME" ];
if [ ! -e "$1/${RPI_ZIP_NAME}" ];
then
echo "$(date) | 1. Downloading original Linux distribution"
wget -nv -O $1/$RPI_ZIP_NAME $2
wget -nv -O $1/${RPI_ZIP_NAME} $2
echo "$(date) | Downloading complete"
else
echo "$(date) | 1. Linux distribution already donwloaded"
fi
echo "$(date) | 2. Unzipping Linux distribution image"
local RPI_IMAGE_NAME=$(echo $RPI_ZIP_NAME | sed 's/zip/img/')
unzip -p $1/$RPI_ZIP_NAME $RPI_IMAGE_NAME > $1/$3
local RPI_IMAGE_NAME=$(echo ${RPI_ZIP_NAME} | sed 's/zip/img/')
unzip -p $1/${RPI_ZIP_NAME} ${RPI_IMAGE_NAME} > $1/$3
echo "$(date) | Unzipping complete"
}
@@ -63,9 +63,9 @@ resize_fs() {
&& local DEV_IMAGE=$(losetup -Pf $1 --show) \
&& sleep 0.5 \
&& echo -e "\033[0;31m\033[1mMount loop-image: $1\033[0m\033[0m" \
&& echo ", +" | sfdisk -N ${ROOT_PARTITION} $DEV_IMAGE \
&& echo ", +" | sfdisk -N ${ROOT_PARTITION} ${DEV_IMAGE} \
&& sleep 0.5 \
&& losetup -d $DEV_IMAGE \
&& losetup -d ${DEV_IMAGE} \
&& sleep 0.5 \
&& local DEV_IMAGE=$(losetup -Pf $1 --show) \
&& sleep 0.5 \
@@ -74,7 +74,7 @@ resize_fs() {
&& echo -e "\033[0;31m\033[1mExpand filesystem\033[0m\033[0m" \
&& resize2fs "${DEV_IMAGE}p${ROOT_PARTITION}" \
&& echo -e "\033[0;31m\033[1mUmount loop-image\033[0m\033[0m" \
&& losetup -d $DEV_IMAGE
&& losetup -d ${DEV_IMAGE}
set -e
}
@@ -82,7 +82,7 @@ resize_fs() {
mount_system() {
# STATIC FUNCTION
# TEMPLATE: mount_system $IMAGE $MOUNT_POINT
# TEMPLATE: mount_system $IMAGE
# Partitions numbers
local BOOT_PARTITION=1
@@ -98,48 +98,49 @@ mount_system() {
local DEV_IMAGE=$(losetup -Pf $1 --show)
sleep 0.5
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m"
#mount $3 $2
#mount $4 $2/boot
mount "${DEV_IMAGE}p${ROOT_PARTITION}" $2
mount "${DEV_IMAGE}p${BOOT_PARTITION}" $2/boot
# Get temp directory to mount image
local MOUNT_POINT=$(mktemp -d)
echo -e "\033[0;31m\033[1mMount dirs ${MOUNT_POINT} & ${MOUNT_POINT}/boot\033[0m\033[0m"
mount "${DEV_IMAGE}p${ROOT_PARTITION}" ${MOUNT_POINT}
mount "${DEV_IMAGE}p${BOOT_PARTITION}" ${MOUNT_POINT}/boot
echo -e "\033[0;31m\033[1mBind system dirs\033[0m\033[0m"
# https://github.com/debian-pi/raspbian-ua-netinst/issues/314
echo "Mounting /proc in chroot... "
if [ ! -d $2/proc ] ; then
mkdir -p $2/proc \
&& echo "Created $2/proc"
if [ ! -d ${MOUNT_POINT}/proc ] ; then
mkdir -p ${MOUNT_POINT}/proc \
&& echo "Created ${MOUNT_POINT}/proc"
fi
mount -t proc -o nosuid,noexec,nodev proc $2/proc \
mount -t proc -o nosuid,noexec,nodev proc ${MOUNT_POINT}/proc \
&& echo "OK"
echo "Mounting /sys in chroot... "
if [ ! -d $2/sys ] ; then
mkdir -p $2/sys \
&& echo "Created $2/sys"
if [ ! -d ${MOUNT_POINT}/sys ] ; then
mkdir -p ${MOUNT_POINT}/sys \
&& echo "Created ${MOUNT_POINT}/sys"
fi
mount -t sysfs -o nosuid,noexec,nodev sysfs $2/sys \
mount -t sysfs -o nosuid,noexec,nodev sysfs ${MOUNT_POINT}/sys \
&& echo "OK"
echo "Mounting /dev/ and /dev/pts in chroot... " \
&& mkdir -p -m 755 $2/dev/pts \
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs $2/dev \
&& mount -t devpts -o gid=5,mode=620 devpts $2/dev/pts \
&& mkdir -p -m 755 ${MOUNT_POINT}/dev/pts \
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs ${MOUNT_POINT}/dev \
&& mount -t devpts -o gid=5,mode=620 devpts ${MOUNT_POINT}/dev/pts \
&& echo "OK"
# mount -t devpts none "$2/dev/pts" -o ptmxmode=0666,newinstance
# ln -fs "pts/ptmx" "$2/dev/ptmx"
# mount -t devpts none "${MOUNT_POINT}/dev/pts" -o ptmxmode=0666,newinstance
# ln -fs "pts/ptmx" "${MOUNT_POINT}/dev/ptmx"
# mount -o bind /dev $2/dev
# mount -t proc proc $2/proc
# mount -t devpts devpts $2/dev/pts
# mount -o bind /dev ${MOUNT_POINT}/dev
# mount -t proc proc ${MOUNT_POINT}/proc
# mount -t devpts devpts ${MOUNT_POINT}/dev/pts
# mount -t proc proc $2/proc
# mount -t sysfs sys $2/sys
# mount --bind /dev $2/dev
# mount -t proc proc ${MOUNT_POINT}/proc
# mount -t sysfs sys ${MOUNT_POINT}/sys
# mount --bind /dev ${MOUNT_POINT}/dev
echo -e "\033[0;31m\033[1mCopy DNS records\033[0m\033[0m" \
&& cp -L /etc/resolv.conf $2/etc/resolv.conf
&& cp -L /etc/resolv.conf ${MOUNT_POINT}/etc/resolv.conf
# https://wiki.archlinux.org/index.php/Change_root_(%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9)
# http://www.unix-lab.org/posts/chroot/
@@ -148,15 +149,15 @@ mount_system() {
# http://unixteam.ru/content/virtualizaciya-ili-zapuskaem-prilozhenie-v-chroot-okruzhenii-razmyshleniya
# http://help.ubuntu.ru/wiki/%D0%B2%D0%BE%D1%81%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_grub
echo -e "\033[0;31m\033[1mEnter chroot\033[0m\033[0m" \
&& chroot $2 /bin/bash
&& chroot ${MOUNT_POINT} /bin/bash
umount_system $2 $DEV_IMAGE
umount_system ${MOUNT_POINT} ${DEV_IMAGE}
}
execute() {
# STATIC FUNCTION
# TEMPLATE: execute $IMAGE $MOUNT_POINT $EXECUTE_FILE ...
# TEMPLATE: execute $IMAGE $EXECUTE_FILE ...
# Partitions numbers
local BOOT_PARTITION=1
@@ -166,56 +167,59 @@ execute() {
local DEV_IMAGE=$(losetup -Pf $1 --show)
sleep 0.5
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m"
mount "${DEV_IMAGE}p${ROOT_PARTITION}" $2
mount "${DEV_IMAGE}p${BOOT_PARTITION}" $2/boot
# Get temp directory to mount image
local MOUNT_POINT=$(mktemp -d)
echo -e "\033[0;31m\033[1mMount dirs ${MOUNT_POINT} & ${MOUNT_POINT}/boot\033[0m\033[0m"
mount "${DEV_IMAGE}p${ROOT_PARTITION}" ${MOUNT_POINT}
mount "${DEV_IMAGE}p${BOOT_PARTITION}" ${MOUNT_POINT}/boot
echo -e "\033[0;31m\033[1mBind system dirs\033[0m\033[0m"
echo "Mounting /proc in chroot... "
if [ ! -d $2/proc ] ; then
mkdir -p $2/proc
echo "Created $2/proc"
if [ ! -d ${MOUNT_POINT}/proc ] ; then
mkdir -p ${MOUNT_POINT}/proc
echo "Created ${MOUNT_POINT}/proc"
fi
mount -t proc -o nosuid,noexec,nodev proc $2/proc \
mount -t proc -o nosuid,noexec,nodev proc ${MOUNT_POINT}/proc \
&& echo "OK"
echo "Mounting /sys in chroot... "
if [ ! -d $2/sys ] ; then
mkdir -p $2/sys
echo "Created $2/sys"
if [ ! -d ${MOUNT_POINT}/sys ] ; then
mkdir -p ${MOUNT_POINT}/sys
echo "Created ${MOUNT_POINT}/sys"
fi
mount -t sysfs -o nosuid,noexec,nodev sysfs $2/sys \
mount -t sysfs -o nosuid,noexec,nodev sysfs ${MOUNT_POINT}/sys \
&& echo "OK"
echo "Mounting /dev/ and /dev/pts in chroot... " \
&& mkdir -p -m 755 $2/dev/pts \
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs $2/dev \
&& mount -t devpts -o gid=5,mode=620 devpts $2/dev/pts \
&& mkdir -p -m 755 ${MOUNT_POINT}/dev/pts \
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs ${MOUNT_POINT}/dev \
&& mount -t devpts -o gid=5,mode=620 devpts ${MOUNT_POINT}/dev/pts \
&& echo "OK"
echo -e "\033[0;31m\033[1mCopy DNS records\033[0m\033[0m" \
&& cp -L /etc/resolv.conf $2/etc/resolv.conf
&& cp -L /etc/resolv.conf ${MOUNT_POINT}/etc/resolv.conf
echo -e "\033[0;31m\033[1m$(date) | Enter chroot\033[0m\033[0m"
script_name=$(basename $3)
script_path_root="$2/root/$script_name"
local script_name=$(basename $2)
local script_path_root="${MOUNT_POINT}/root/${script_name}"
# Copy script into chroot fs
# TODO: Find more suitable location for temporary script storage
cp "$3" "$script_path_root"
cp "$2" "${script_path_root}"
# Its important to save arguments (direct ${@:4} causes problems)
script_args="${@:4}"
script_args="${@:3}"
# Run script in chroot with additional arguments
chroot $2 /bin/sh -c "/root/$script_name $script_args"
chroot ${MOUNT_POINT} /bin/sh -c "/root/${script_name} ${script_args}"
# Removing script from chroot fs
rm "$script_path_root"
rm "${script_path_root}"
umount_system $2 $DEV_IMAGE
umount_system ${MOUNT_POINT} ${DEV_IMAGE}
}
copy_to_chroot() {
# STATIC FUNCTION
# TEMPLATE: copy_to_chroot $IMAGE $MOUNT_POINT $MOVE_FILE
# TEMPLATE: copy_to_chroot $IMAGE $MOVE_FILE $MOVE_TO
# Partitions numbers
local BOOT_PARTITION=1
@@ -225,44 +229,25 @@ copy_to_chroot() {
local DEV_IMAGE=$(losetup -Pf $1 --show)
sleep 0.5
echo -e "\033[0;31m\033[1mMount dirs $2 & $2/boot\033[0m\033[0m"
mount "${DEV_IMAGE}p${ROOT_PARTITION}" $2
mount "${DEV_IMAGE}p${BOOT_PARTITION}" $2/boot
# Get temp directory to mount image
local MOUNT_POINT=$(mktemp -d)
echo -e "\033[0;31m\033[1mBind system dirs\033[0m\033[0m"
echo "Mounting /proc in chroot... "
if [ ! -d $2/proc ] ; then
mkdir -p $2/proc
echo "Created $2/proc"
fi
mount -t proc -o nosuid,noexec,nodev proc $2/proc \
&& echo "OK"
echo "Mounting /sys in chroot... "
if [ ! -d $2/sys ] ; then
mkdir -p $2/sys
echo "Created $2/sys"
fi
mount -t sysfs -o nosuid,noexec,nodev sysfs $2/sys \
&& echo "OK"
echo "Mounting /dev/ and /dev/pts in chroot... " \
&& mkdir -p -m 755 $2/dev/pts \
&& mount -t devtmpfs -o mode=0755,nosuid devtmpfs $2/dev \
&& mount -t devpts -o gid=5,mode=620 devpts $2/dev/pts \
&& echo "OK"
echo -e "\033[0;31m\033[1mCopy DNS records\033[0m\033[0m" \
&& cp -L /etc/resolv.conf $2/etc/resolv.conf
echo -e "\033[0;31m\033[1mMount dirs ${MOUNT_POINT} & ${MOUNT_POINT}/boot\033[0m\033[0m"
mount "${DEV_IMAGE}p${ROOT_PARTITION}" ${MOUNT_POINT}
mount "${DEV_IMAGE}p${BOOT_PARTITION}" ${MOUNT_POINT}/boot
echo -e "\033[0;31m\033[1m$(date) | Enter chroot\033[0m\033[0m"
script_name=$(basename $3)
script_path_root="$2/root/$script_name"
file_name=$(basename $2)
file_path_root="${MOUNT_POINT}$3/${file_name}"
# Copy script into chroot fs
# TODO: Find more suitable location for temporary script storage
cp "$3" "$script_path_root"
if [ ! -d ${file_path_root} ] ; then
mkdir -p ${file_path_root} \
&& echo "Created ${file_path_root}"
fi
cp "$2" "${file_path_root}"
umount_system $2 $DEV_IMAGE
umount_system ${MOUNT_POINT} ${DEV_IMAGE}
}
umount_system() {
@@ -317,6 +302,8 @@ publish_image() {
echo -e "\033[0;31m\033[1m$(date) | Zipping complete!\033[0m\033[0m"
else
echo -e "\033[0;31m\033[1m$(date) | Zip-archive already created\033[0m\033[0m"
cd $1 && rm $2.zip && zip $2.zip $2
echo -e "\033[0;31m\033[1m$(date) | Old archive was deleted & create new\033[0m\033[0m"
fi
echo -e "\033[0;31m\033[1m$(date) | Upload image\033[0m\033[0m"
@@ -370,8 +357,8 @@ echo "\$7: $7"
case "$1" in
mount_system)
# mount_system $IMAGE $MOUNT_POINT
mount_system $2 $3;;
# mount_system $IMAGE
mount_system $2;;
get_image)
# get_image $BUILD_DIR $RPI_DONWLOAD_URL $IMAGE_NAME
@@ -386,11 +373,11 @@ case "$1" in
publish_image $2 $3 $4 $5 $6 "$7";;
execute)
# execute $IMAGE $MOUNT_POINT $EXECUTE_FILE ...
execute $2 $3 $4 ${@:5};;
# execute $IMAGE $EXECUTE_FILE ...
execute $2 $3 ${@:4};;
copy_to_chroot)
# copy_to_chroot $IMAGE $MOUNT_POINT $MOVE_FILE
# copy_to_chroot $IMAGE $MOVE_FILE $MOVE_TO
copy_to_chroot $2 $3 $4;;
*)

View File

@@ -7,7 +7,6 @@ set -e
##################################################################################################################################
# ros http://wiki.ros.org/action/fullsearch/ROSberryPi/Installing%20ROS%20Kinetic%20on%20the%20Raspberry%20Pi
# maintainer @urpylka
echo -e "\033[0;31m\033[1m$(date) | Installing ROS\033[0m\033[0m"
@@ -42,8 +41,8 @@ echo -e "\033[0;31m\033[1m$(date) | #4 rosdep init && rosdep update\033[0m\033[0
# bootstrap rosdep
rosdep init && rosdep update
# If $2 = false, then discover packages
if [ "$2" = "false" ];
# If $3 = false, then discover packages
if [ "$3" = "false" ];
then
echo -e "\033[0;31m\033[1m$(date) | #5 Preparing ros_comm packages to kinetic-ros_comm-wet.rosinstall\033[0m\033[0m"
@@ -64,7 +63,6 @@ else
echo -e "\033[0;31m\033[1m$(date) | #5 Creating manual ros_catkin_ws\033[0m\033[0m"
mkdir -p /home/pi/ros_catkin_ws && cd /home/pi/ros_catkin_ws \
&& mv /root/kinetic-ros-coex.rosinstall kinetic-ros-coex.rosinstall \
&& wstool init src kinetic-ros-coex.rosinstall
fi
@@ -132,6 +130,8 @@ chown -Rf pi:pi /home/pi/ros_catkin_ws
echo -e "\033[0;31m\033[1m$(date) | #12 Creating catkin_ws & Installing CLEVER-BUNDLE\033[0m\033[0m"
git clone $1 /home/pi/catkin_ws/src/clever \
&& cd /home/pi/catkin_ws/src/clever \
&& git checkout $2 \
&& pip install wheel \
&& pip install -r /home/pi/catkin_ws/src/clever/clever/requirements.txt \
&& cd /home/pi/catkin_ws \