socialgekon.com
  • Основен
  • Разпределени Екипи
  • Публикуване
  • Управление На Проекти
  • Мобилен Дизайн
Back-End

Въведение в роботизираната операционна система: Най-новата рамка за приложения на роботиката

The Роботизирана операционна система (ROS) всъщност не е операционна система, а рамка и набор от инструменти, които осигуряват функционалността на операционната система на хетерогенна група компютри. Полезността му не се ограничава до роботи, но повечето от предоставените инструменти се фокусират върху работата с периферен хардуер.

ROS Разделен е на повече от 2000 пакета, всеки пакет има специализирана функционалност. Броят на инструментите, свързани с рамката, е може би най-голямата й сила.

Защо да използвам SO Robot?

ROS предоставя функционалност за абстракция на хардуер, драйвери на устройства, комуникация между процесите на множество машини, инструменти за тестване и визуализация и много други.



Въведение в роботизираната операционна система: Най-новата рамка за приложения на роботиката

Ключовата характеристика на ROS е начинът, по който софтуерът работи и комуникира, което ви позволява да проектирате сложен софтуер, без да знаете как работи определен хардуер. ROS осигурява начин за свързване на основна мрежа от процеси (възли). Възлите могат да работят на множество устройства и да се свързват с този хъб по различни начини.

Основните начини за създаване на мрежа са предоставяне на необходимите услуги или определяне на връзки между рекламодатели или абонати с други възли. И двата метода комуникират чрез специфични видове съобщения. Някои типове се предоставят от основните пакети, но типовете съобщения могат да бъдат дефинирани от отделни пакети.

Разработчиците могат да съставят сложна система, като свържат съществуващите решения за малки проблеми. Начинът, по който системата е внедрена, ни позволява да:

  • Заменяйте компонентите с подобни интерфейси в движение, премахвайки необходимостта от спиране на системата за различни промени.

  • Мултиплексирайте изхода на множество компоненти към вход за друг компонент, позволявайки паралелно решаване на различни проблеми.

  • Свържете компоненти, направени на различни програмни езици, като просто внедрите подходящите съединители към системата за съобщения, улеснявайки разработването на софтуер чрез свързване на съществуващи модули от различни разработчици.

  • Създайте възли в мрежа от устройства, без да се притеснявате къде се изпълнява код и внедрете системите за комуникация между процес (IPC) и извикване на отдалечена процедура (RPC).

  • Свържете се директно с отдалечени хардуерни потоци при поискване, без да пишете допълнителен код, като използвате предишните две точки.

Планираме да покажем колко полезно е чрез итеративно разработване на просто решение. Има няколко ключови предимства в сравнение с други подходи. ROS има поддръжка на различни платформи и позволява връзки между процеси на множество устройства, чрез връзки на връстници, които се обработват зад кулисите. Дизайнът позволява поддръжка за всеки език при определяне на комуникационните класове C ++ или ръчно разработване на класове за езиковия интерфейс.

ROS се прави от собствена общност. След няколко години това доведе до голям брой пакети за многократна употреба, които са лесни за интегриране благодарение на системната архитектура.

Алтернативни подходи като MRPT , КАРМЕН , LCM , Играч , Microsoft RDS а други предоставят някои, но не всички от тези функции. През повечето време конструктивните недостатъци са ограничения на езиковата поддръжка, лоша комуникация между процесите или липса на поддръжка за различни устройства, което е може би най-трудният проблем за решаване.

Какво ще строим?

Тъй като фокусът ни е върху рамката, а не върху алгоритмите като такива, за конкретни проблеми, даденият проблем ще бъде много прост. Нашата цел е да създадем софтуер за компютър, който е част от процеса и ни позволява дистанционно да контролираме и наблюдаваме робот, свързан с нас чрез Wi-Fi, използвайки геймпад на нашия компютър и предаване от камерата, монтирана на робота .

На първо място, ще свържем проста програма с проста симулация, само за да демонстрираме основните принципи на ROS. Ще свържем геймпад към компютър и ще се опитаме да създадем добра схема за управление, за да предадем входа на геймпада за управление на сигнали за робот.

Основните езици за писане на ROS код са C ++ и Python, C ++ се предпочита за по-ниска производителност. Ще обясним нашите примери в Python тъй като има по-малко квалификатор в кода и не е необходимо да се прави конкретна конструкция.

Инсталиране и конфигуриране

Версиите на ROS са посочени по име. Към днешна дата най-новата версия е Нефритна костенурка , а LTS версията е Индиго иглу . Преминаването от версия е за предпочитане и обратната съвместимост не е гарантирана в ROS, така че всички примери ще бъдат написани за Индиго .

ROS се предлага на различни * NIX платформи. Официално поддържаната версия е на Ubuntu. Версиите на OS X, Arch Linux, Debian, Raspbian и Android се поддържат от общността.

Ще видим процеса на инсталиране на Ubuntu 14.04 на десктоп. Процесите за всички поддържани версии и платформи са налични в официален уебсайт . Предлагат се и виртуални машини с вече инсталиран ROS.

Инсталацията зависи от платформата (и повечето платформи имат пакетни пакети), но настройките на работното пространство са еднакви за всички платформи. .

Инсталация в Ubuntu

ROS предоставя свои собствени хранилища. Първата стъпка е да ги добавите.

sudo sh -c 'echo 'deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main' > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver hkp://pool.sks-keyservers.net --recv-key 0xB01FA116 sudo apt-get update

След това ще имате всички хоствани пакети за всички версии на ROS, налични за вашата версия на Ubuntu. Например Ubuntu 14.04 поддържа indigo и jade.

Инсталирането на базовите пакети на настолен компютър има една от трите опции:

  • sudo apt-get install ros-indigo-ros-base за минимален монтаж

  • sudo apt-get install ros-indigo-desktop да имате допълнителен основен инструмент за графичен интерфейс

  • sudo apt-get install ros-indigo-desktop-full да има всички официални функции, включително различни симулатори и библиотеки за навигация и възприятие.

За по-добър трудов опит се препоръчва пълната опция. За инсталиране на устройства, които ще се използват само за стартиране на възли, версията ase е достатъчна. Но без значение коя опция изберете, можете да инсталирате всеки пакет, който ви трябва, наречен package_name при изпълнение:

sudo apt-get install ros-indigo-

Подчертанията се заменят с тирета в окончателното име, така че stage_ros ще бъде в пакета като ros-indigo-stage-ros.

Следващата стъпка е да започнете rosdep. Пакетите в ROS могат да декларират от кои компоненти зависят. rosdep ви позволява да компилирате тези пакети, без да разчитате твърде много на ръчно боравене. За да го стартирате, обадете се:

sudo rosdep init rosdep update

ROS има много променливи на околната среда, използвани от неговите инструменти. С инсталацията по подразбиране, скриптът баш за да ги стартира се намира в /opt/ros/indigo/setup.bash. Променливите трябва да се стартират в рамките на всяка сесия от баш , така че най-доброто решение е да ги добавите към ~/.bashrc.

echo 'source /opt/ros/indigo/setup.bash' >> ~/.bashrc source ~/.bashrc

Някои пакети инсталират външни зависимости чрез rosinstall, който се предлага като пакет и се инсталира чрез sudo apt-get install python-rosinstall.

Това е краят на инсталацията на Ubuntu. Следва кратко въведение в настройката на работното пространство.

Настройка

От Groovy Galapagos , ROS работните пространства са управлявани чрез catkin. Трябва да дефинираме директория за всички пакети, които хостваме. Вътре в директорията създаваме папка src и извикваме catkin_init_workspace отвътре. Това ще създаде няколко символни връзки в текущата версия на ROS. Следващата стъпка е също да добавите това работно пространство към променливите на средата.

За да изпълните всички тези настройки на работното пространство, изберете празна директория и изпълнете следните команди:

mkdir src cd src catkin_init_workspace cd .. catkin_make echo 'source $(pwd)/devel/setup.bash' >> ~/.bashrc source ~/.bashrc

Вече сте създали работно пространство, където можете да създадете свои собствени ROS пакети.

Запознайте се с инструментите

Създаването на какъвто и да е код е огромен скок. Първо, нека се запознаем с някои системи, работещи зад кулисите. Първата ни стъпка ще бъде да стартираме основния GUI и да видим какви съобщения той генерира.

За да стартирате каквото и да е в ROS, трябва да стартирате основен процес. Това е толкова лесно, колкото отварянето на нов прозорец на терминала и въвеждането:

roscore

В мрежата на свързаното ви устройство, roscore трябва да се изпълни само веднъж на устройството, което ще бъде домакин на централния хъб за изпращане на комуникация.

Основната роля на roscore това е да се каже на възлите, към които трябва да се свържат други възли, и по какъв начин (чрез мрежов порт или споделена памет). Целта е да се позволи на възлите да се притесняват само за това кои данни искат да знаят, а не към кой възел искат да се свържат, като същевременно минимизират времето или честотната лента, необходими им за осъществяване на цялата комуникация.

rqt

След като стартираме roscore, можем да стартираме основния GUI инструмент за ROS: rqt. Това, което виждаме, е много разочароващо - празен прозорец. rqt Той хоства голямо разнообразие от приставки, които могат да бъдат конфигурирани във всяка визуална конфигурация и произволен брой предварително дефинирани изгледи.

За начало стартираме приставката Управление на робот , като го изберете в Plugins > Robot Tools > Robot Steering. Това, което получаваме, са два плъзгача, които представляват линейното и въртеливото движение, които искаме да има нашият робот. В горната част на приставката виждаме текстово поле с /cmd_vel в нея. Можем да му дадем друго име. Представлява името на темата, към която е насочена публикацията. Терминалните инструменти са най-доброто място да видите какво се случва във фонов режим.

Терминални инструменти

ROS разполага с няколко мощни инструмента за проверка на случващото се в системата. Първият инструмент, който ще въведем, е rostopic, той ни позволява да проверяваме теми, за които възлите могат да се абонират и публикуват. Изпълнение rostopic list давам на:

/cmd_vel /rosout /rosout_agg

Последните две теми винаги се изпълняват и са свързани с основните ROS системи. Темата /cmd_vel се публикува от нашите адреси. Преименуването на темата в адресите ще я преименува и тук. Сега ни интересува какво се случва в темата. Изпълнение rostopic echo /cmd_vel няма да ни покаже нищо (освен ако не играете с плъзгачите). Процесът протича, докато не го отменим. Сега нека преместим вертикалния плъзгач с 20 m / s. Поглеждайки към ехото, можем да видим следното, повтаряно отново и отново:

linear: x: 0.2 y: 0.0 z: 0.0 angular: x: 0.0 y: 0.0 z: 0.0

Колко често това съобщение спам? rostopic hz /cmd_vel пише със средна скорост от 10 Hz. Е, колко песни като тази мога да изпълня на бавната си Wi-Fi връзка? rostopic bw /cmd_vel открива средно 480 B / s.

Всичко това е много добре, но говорим за типове съобщения. Тези данни са добри за човек, но приложението ще се нуждае от сурови данни и ще трябва да знае типа на съобщението, за да интерпретира данните. Типът на съобщението може да се интерпретира с rostopic type /cmd_vel, като ни казва, че е geometry_msgs/Twist. Всички терминални инструменти на ROS, извикани без аргументи, връщат стандартно съобщение за помощ.

ROS Wiki е подходящ за уеб търсене на този резултат от низове, в обяснение на Wiki за това какво съдържа и как е структурирано. Но не е нужно да му вярваме. rosmsg е основният инструмент за типовете съобщения. Изпълнение rosmsg show geometry_msgs/Twist връщане:

geometry_msgs/Vector3 linear float64 x float64 y float64 z geometry_msgs/Vector3 angular float64 x float64 y float64 z

Съобщението се състои от два 3D вектора, представящи линейна и ъглова скорост в 3D пространството.

Ако искате да знаете към какви теми се свързва възел, rosnode info Ще ни даде подробни данни за възела. Инструментите rostopic, rosmsg и rosnode са основните инструменти за проверка на неполирана ROS функционалност. ROS има много повече GUI и терминални инструменти, но те са извън обхвата в това въведение.

Основните инструменти за стартиране на ROS възел са rusrun и roslaunch. rosrun можете да изпълнявате възли чрез rosrun и roslaunch той изпълнява възли, базирани на стартови файлове, с които ще се запознаем малко, тъй като те са най-сложният елемент на ROS автоматизацията.

Можем да изключим всичко, което изпълняваме, за да започнем да работим върху първия си код. За бъдещи справки ще бъде очевидно, че стартирането на всичко, свързано с ROS, изисква активен екземпляр на roscore. Много от проблемите, с които се сблъсквате, могат да бъдат решени чрез затваряне на работещия прозорец на терминала roscore и отворете нов, за да го рестартирате. Това актуализира всички зависимости, които трябваше да бъдат презаредени, както в bash и в roscore.

Създаване на геймпад за телеоперация

Първата ни цел е да имитираме функционалността на Robot Steering създаване на възел, който публикува данни от geometry_msgs/Twist a /cmd_vel въз основа на вход за геймпад. Първата ни спирка е пакетът joy

Пакетът joy

Пакетът joy предоставя общи ROS драйвери за джойстик и геймпади. Той не е включен в инсталацията по подразбиране, така че трябва да бъде инсталиран чрез:

sudo apt-get install ros-indigo-joy

След инсталацията можем да стартираме rosrun joy joy_node. Това по подразбиране ще ни свърже с джойстика или геймпада. Изпълнение rostopic list ни показва, че имаме тема, наречена /joy. Слушайте чрез rostopic echo Показва ни съобщения от следния формат (имайте предвид, че трябва да взаимодействате с геймпада или джойстика, за да бъдат публикувани съобщенията).

header: seq: 4156 stamp: secs: 1450707466 nsecs: 204517084 frame_id: '' axes: [0.0, 0.0, 0.0, -0.0, 0.0, 0.0, 0.0, 0.0] buttons: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Засега можете да игнорирате заглавките. Освен това имаме axes и buttons, които добре обясняват какво представляват. Чрез преместване на брадви и натиснете бутони в контролера, това ще доведе до промяна на тези числа. Използвайки нашите инструменти, можем да определим, че типът на съобщението е sensor_msgs/Joy и форматът е:

std_msgs/Header header uint32 seq time stamp string frame_id float32[] axes int32[] buttons

Създаване на нашата телеоперация

Първата стъпка при писане на код е създаването на пакет. Вътре в папката src от работното пространство, изпълнете:

catkin_create_pkg toptal_tutorial rospy joy geometry_msgs sensor_msgs

Тук посочваме името на пакета, който създаваме, последвано от пакети, от които планираме да разчитаме. Не се притеснявайте, зависимостите могат да се актуализират ръчно, по-късно.

Сега имаме папка toptal_tutorial. Вътре в папката създайте папка, наречена scripts който ще съдържа всички наши Python скриптове.

Нека създадем файл, наречен teleop.py, и вътре в него ще имаме:

#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy def joy_callback(data): print data def main(): rospy.init_node('teleop') rospy.Subscriber('joy', Joy, joy_callback) while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

Също така трябва да зададем chmod +x teleop.py по този начин скриптът е изпълним. Изпълнение rosrun joy joy_node в терминал и rosrun toptal_tutorial teleop.py в друга ще доведе до изхода на терминала teleop.py да бъде запълнен със съобщения Радост .

Нека разгледаме какво прави кодът.

Първо, ние внасяме роспи , в която се намира библиотеката за взаимодействие с ROS рамката. Всеки пакет, който дефинира съобщения, има подпакет msg с дефиниции на съобщения. Внасяме Joy за обработка на въвеждането. Няма нужда да импортирате вградени типове съобщения (като Header от std_msgs.msg това в съобщението Joy), освен ако не искаме специално да ги споменем.

Първата ни стъпка е да инициализираме възел с конкретно име (в този случай го наричаме „teleop“). След това създаваме абонат, който се абонира за темата тип 'радост' sensor_msgs.msg.Joy и който обработва всяко съобщение, като извиква функцията joy_callback Обратните обаждания получават параметър, данните за съобщението. Достъпът до членовете на данни е лесен. Ако искахме да отпечатаме състоянието на първия ос , ако си спомним типа на съобщението, бихме извикали print data.axes[0] и това би било float. Възелът в края на възлите, докато ROS изгасне.

Следващата ни стъпка ще бъде да управляваме данните си по някакъв начин. Трябва да създадем съобщение Извийте това се променя в зависимост от входа и след това ще го публикуваме в темата cmd_vel

#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist # new from functools import partial # new def joy_callback(pub, data): # modified cmd_vel = Twist() # new cmd_vel.linear.x = data.axes[1] # new cmd_vel.angular.z = data.axes[0] # new pub.publish(cmd_vel) # new def main(): rospy.init_node('teleop') pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) # new rospy.Subscriber('joy', Joy, partial(joy_callback, pub)) # modified while not rospy.is_shutdown(): pass if __name__ == '__main__': main()

Първо добавяме съобщението Twist и добавяме поддръжка за функционални аргументи с обвързвания чрез functools.partial. Създаваме рекламодател, pub, който публикува в cmd_vel тип съобщение Twist. Ние обвързваме този рекламодател с обратното обаждане и го караме да публикува съобщение Извийте във всеки запис, като скоростите са представени от първите две брадви . Този код прави това, което се очаква от него, и можем да видим получения резултат чрез rostopic echo /cmd_vel.

Все още имаме проблем. Темата /joy може да публикува големи скорости. Ако наблюдаваме rostopic hz /cmd_vel и движим аналоговия стик в кръгове, можем да видим много съобщения. Това ще доведе не само до голям брой комуникации, но и процесите, които получават тези съобщения, трябва да обработят всяка една от тях; няма нужда да публикувате толкова много данни толкова често и всъщност е по-добре да публикувате със стабилна скорост от 10 Hz. Можем да получим това със следния код.

#!/usr/bin/env python import rospy from sensor_msgs.msg import Joy from geometry_msgs.msg import Twist from functools import partial def joy_callback(cmd_vel, data): # modified cmd_vel.linear.x = data.axes[1] cmd_vel.angular.z = data.axes[0] # moved pub.publish(cmd_vel) to main loop def main(): rospy.init_node('teleop') cmd_vel = Twist() # new pub = rospy.Publisher('cmd_vel', Twist, queue_size=1000) rospy.Subscriber('joy', Joy, partial(joy_callback, cmd_vel)) # modified rate = rospy.Rate(10) # new while not rospy.is_shutdown(): pub.publish(cmd_vel) # new rate.sleep() # new if __name__ == '__main__': main()

Модифицираме обратно извикване, за да получим изменяемия обект Twist и го модифицирайте вътре в цикъла. Функцията sleep от rospy.Rate поддържа стабилна изходна честота.

Крайният код ще доведе до темата /cmd_vel получаване на командни скорости от 10 Hz, като по този начин имитира изхода на приставката Управление на робот rqt

Стартиране на симулирана система

Симулиране на света

Първата ни цел е да създадем среда, в която можем да симулираме сценария, който искаме да постигнем. Възелът stageros вътре в пакета stage_ros Това ще ни позволи да изпълним робот в 2D етап, определен от изображение. Има цял синтез, описан в пакет stage_ros за световните архиви и как да ги генерирам. Това е доста лесно, но недостъпно. За щастие пакетът идва с няколко световни демонстрации. Първо нека отидем в директорията с файлове чрез изпълнение:

roscd stage_ros cd world

Вътре в папката има няколко файла. Да пуснем една.

rosrun stage_ros stageros willow-erratic.world

Създадени са различни теми. Значението на всеки от тях също е документирано с пакета. Важното е, че има cmd_vel.

В рамките на показаната сцена има синя кутия, това представлява робота, който контролирате. Като използвате нашия код или Управление на робот можем да контролираме този робот. Опитай!

Конфигуриране на нашата система с помощта на стартови файлове

Първо създаваме папка launch или lanzamiento вътре в нашия пакет и вътре в него създайте файл, наречен teleop.launch. Окончателната структура на папката трябва да изглежда така:

toptal_tutorial/ ├── CMakeLists.txt ├── launch │ └── teleop.launch ├── package.xml ├── scripts │ └── teleop.py └── src

Във файла teleop.launch Ще дефинираме няколко възли и техните взаимовръзки.

robot_

Новият свят се състои от 4 робота и всяка от техните теми има префикс, наречен robot_0/cmd_vel. По този начин робот номер 0 има тема за скоростта на командата, наречена robot_0. Ето защо поставяме контрола си в пространството от имена, наречено roscore и така ще приспособим имената им към новата форма. По този начин можете да мислите за имената на теми като папки във файлова система.

Не е необходимо roscore да стартирате стартови файлове. По някакъв начин, roscore това е само специален случай на стартов файл, който не прави нищо. Ако a roslaunch toptal_tutorial teleop.launch само първият стартиран файл ще стартира ядро, докато останалите ще се свържат с него. Сега ще изпълним стартирането с:

/robot_/base_pose_ground_truth /robot_/base_scan_0 /robot_/base_scan_1 /robot_/camera_info_0 /robot_/camera_info_1 /robot_/cmd_vel /robot_/depth_0 /robot_/depth_1 /robot_/image_0 /robot_/image_1 /robot_/odom

Ако всичко е наред, това ще доведе до симулатор с 4 робота, където всеки от тях се управлява с геймпада или джойстика. Този свят има много повече съдържание от предишния. Всеки от четирите робота има следното:

rqt

Заменяме с 0, 1, 2 или 3. И с това стигаме до последната ни тема.

Преглед на нашите данни с rqt

Преди това не се задълбочавахме в image_0 но това е идеалният инструмент за визуализиране на по-сложни данни. Можете да експериментирате с всички теми, но ние ще се съсредоточим върху image_1, depth_0, depth_1 и rqt теми.

Изпълнява се Plugins > Visualización > Vista Imagen премахваме всички отворени приставки. Сега ще отворим 4 визуализатора на изображения (robot_0) и ще ги поставим в мрежа 2x2. И накрая, в горния ляв ъгъл на всеки от изгледите ще изберем една от четирите теми, установени за stage_ros/world.

Това, което получаваме, е стерео зрение с дълбоко възприятие с камери с ниска разделителна способност. Имайте предвид, че бихме могли да получим този резултат без нашата система за въвеждане. Ако просто стартираме това (от папката rosrun stage_ros stageros willow-four-erratics-multisensor.world ):

/robot_0/cmd_vel

И ние добавяме приставката Управление на робот с тема, наречена export ROS_MASTER_URI=http://:11311/ Можехме да имаме същия резултат, ако контролите бяха на екрана.

Прилагане на резултатите в реална система

Много хардуер напълно поддържа ROS, често благодарение на трети страни. Много роботизирани платформи имат драйвери, които генерират този тип съобщения, а ROS има възли, които активират уеб камерата и публикуват емисия от изображения.

Докато последният резултат беше симулация на това, което искаме да постигнем; същото може да се постигне със следните модификации:

  • Инсталирайте ROS на бордовия компютър на вашия робот
  • Създава стартиращ файл за бордовия компютър, който свързва ROS с основната платформа и всички сензори на високо ниво като камери, лазерен обхват и други. Необходимите възли може вече да съществуват или могат да бъдат внедрени чрез създаване на издател / абонат за ROS от едната страна и драйвер за серийни комуникации от другата.
  • Накарайте стартовия файл да работи при стартиране
  • На вашия отдалечен компютър добавете rqt когато стартирате в Bash, така че отдалеченият компютър ще гледа този хост и порт
  • Започва gazebo и / или всеки скрипт за наблюдение и управление на робота

В крайна сметка на отдалеченото устройство трябва да се експортира само подходящата променлива среда, а всичко останало се извършва от само себе си. Изпълнението на ROS на компютърен клъстер отнема само една стъпка, за да се подготвите за всяка машина.

заключение

Показахме как с всеки код, колкото и малък да е, можете да имате сложна система от променливи, които можете да манипулирате, както искате. Простата система за издатели / абонати позволява бързо разработване на софтуер, който обработва данни на клъстер от компютри, като същевременно ви оставя спокойствие, така че да не се притеснявате за основното изпълнение на определени елементи.

Докато използваме обикновен симулатор, други по-сложни симулатори като

|_+_|
(което е включено в пълната настолна версия) ви позволява да създавате 3D светове със сложни физически сензори И ви дава опит за крайните резултати и продукта, преди да бъде разработен.

Това въведение беше донякъде основно, но се надяваме, че ще се почувствате по-заинтересовани от работата с тази гъвкава рамка.

Съвети и съображения при избора на шрифт (с инфографика)

Ui Design

Съвети и съображения при избора на шрифт (с инфографика)
Пълен преглед на най-добрите инструменти за визуализация на данни

Пълен преглед на най-добрите инструменти за визуализация на данни

Ui Design

Популярни Публикации
Инсталиране на Django на IIS: Урок стъпка по стъпка
Инсталиране на Django на IIS: Урок стъпка по стъпка
Въведение в търговията с дълбоко обучение в хедж фондове
Въведение в търговията с дълбоко обучение в хедж фондове
Ръководство за здрави модулни и интеграционни тестове с JUnit
Ръководство за здрави модулни и интеграционни тестове с JUnit
Разработване на мобилни уеб приложения: кога, защо и как
Разработване на мобилни уеб приложения: кога, защо и как
Как да накараме отдалечената работа да работи за вас
Как да накараме отдалечената работа да работи за вас
 
Месец в живота - Временни роли на финансовия директор и най-добри практики
Месец в живота - Временни роли на финансовия директор и най-добри практики
Android DDMS: Ръководство за Ultimate Android Console
Android DDMS: Ръководство за Ultimate Android Console
Щъркел, част 2: Създаване на анализатор на изрази
Щъркел, част 2: Създаване на анализатор на изрази
Плащане напред: Разбиране на изкупувания с ливъридж
Плащане напред: Разбиране на изкупувания с ливъридж
Убеждаване и преместване - Ръководство за принципите на дизайна на движението
Убеждаване и преместване - Ръководство за принципите на дизайна на движението
Категории
ИновацияДругиПродукти Хора И ЕкипиAgile TalentUi DesignНачин На ЖивотИнженерно УправлениеПланиране И ПрогнозиранеПъргавПубликуване

© 2023 | Всички Права Запазени

socialgekon.com