tag:blogger.com,1999:blog-8246652173559783682024-03-13T20:36:07.426+03:00Life engineL-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.comBlogger120125tag:blogger.com,1999:blog-824665217355978368.post-62194467527801653892022-12-05T03:33:00.005+03:002023-12-21T19:26:26.777+03:00Блог переехалНовое место: <a href="https://l-proger.ru" target="_blank">https://l-proger.ru</a>L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-67083044742603720582020-02-23T02:39:00.003+03:002020-02-27T02:06:29.896+03:00"RealPad" DualShock(1,2) gamepad plugin for PCSX2 PS2 emulator<div dir="ltr" style="text-align: left;" trbidi="on">
Написал за несколько вечеров код работы (чтение/конфигурация) с игровыми контроллерами Sega, PlayStation1, PlayStation2 под микроконтроллер STM32F7, высунул данные через USB (HID устройство), можно пользоваться как обычным компьютерным геймпадом.<br />
<br />
<i> Я использовал борд с микроконтроллером серии STM32F7 с сайта одного знакомого "электронщика": https://evaluationboard.ru . В борде нет ни чего лишнего и имеется всё необходимое. Например, в нём распаян полностью рабочий программатор ST-Link V2 и установлена микросхема FTDI (USB to COM адаптер), оба они припаяны к хабу, от которого идёт наружу "принтерный" USB разъем. Получаем отладку SWD, UART через 1 кабель и ни каких лишних девайсов/проводов. Остальные плюшки борда можно рассмотреть на сайте, при желании.</i><br />
<br />
Но этого оказалось недостаточно...<br />
<br />
Когда всё заработало, я подумал: а что если реализовать мечту "детства" и написать немного кода для некогда часто мной используемого эмулятора PlayStation2 "PCSX2"?<br />
<br />
Сделал fork pcsx2 проекта на github, разобравшись (со скрипом, т.к. API очень не интуитивно сделан и не документирован) в API эмулятора, накидал быстро код общения с моим хардварным интерфейсом к геймпадам и назвал проект "RealPad" по аналогии с другими плагинам. "Real" - тут важная часть названия, т.к. подключается настоящий геймпад и по-настоящему читается виртуальной PS2 без дополнительных алгоритмов обработки ввода.<br />
<br />
Это самая простая и самая нативная интеграция геймпада, что может быть ) Любая игра может как угодно пользоваться геймпадом - это и чтение данных ввода (любых, включая силу нажатия кнопок) и конфигурация геймпада и т.п.<br />
<br />
Вот что получилось:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/ho4jAdMCPGw/0.jpg" frameborder="0" height="532" src="https://www.youtube.com/embed/ho4jAdMCPGw?feature=player_embedded" width="640"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Ссылка на репозиторий: <a href="https://github.com/L-proger/pcsx2/tree/develop/RealPad">https://github.com/L-proger/pcsx2/tree/develop/RealPad</a></div>
<br />
Disclaimer: код пока что сырой, написан в скоростном режиме как proof of concept. Предстоит его почистить, реализовать правильную выгрузку, поддержку нескольких геймпадов, <strike>починить косяк, когда игры не видят контроллер после загрузки быстрого сохранения (F3)</strike>. А ещё ввод с клавиатуры не работает, когда используется мой плагин, например, не могу использовать "быстрое сохранение" (F1), придётся разобраться что ещё от меня хочет эмулятор.<br />
<br />
В дальнейшем выложу и прошивку под STM32, как только её в порядок приведу )<br />
<br />
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-45666411906891958992019-10-02T20:04:00.001+03:002019-10-02T23:00:45.206+03:00Run Stm32CubeMX & STM32CubeProgrammer applications with OpenJDK on Windows<div dir="ltr" style="text-align: left;" trbidi="on">
Stm32CubeMX требует наличие установленного OracleJRE/JDK и при его отсутствии в системе ругается, что не может найти JRE версии 1.8.0_45 или выше. Кубу всё равно на то, что у меня в системе есть OpenJDK (ставил разные версии, добавлял в PATH, не помогало) и мне на пару секунд даже показалось, что придётся сдаться и поставить ещё и OracleJRE (чего я очень не хотел), но на самом деле сдаваться рано )<br />
<br />
Сначала попробовал изменить требуюмую версию Java в инсталлере куба, но понял, что это не помогает. Потом нашёл и "поставил" именно 1.8.0_45 но OpenJRE а не OracleJRE - всё равно не помогло. Потом нашёл некий интересный путь C:\ProgramData\Oracle\Java\javapath ! В нём лежат 3 симлинка на java.exe, javaw.exe, jawaws.exe.<br />
<br />
Тут я решил, что "вот оно", мне надо эти симлинки создать на соответствующие exe файлы из моей версии OpenJRE. И создал. И не помогло ) Куб при установке ругался всё тем же сообщением.<br />
<br />
Теперь я решил запустить java.exe через мой симлинк и о чудо, java ругнулась, что в реестре не хватает ветки. Я поставил OracleJDK, экспортнул ветку, удалил OracleJDK, импортнул ветку и подправил пути на свои, вычистив лишние ветки/ключи.<br />
<br />
И всё заработало !<br />
<br />
Моя версия OpenJDK лежит по такому пути: C:\openjdk-12.0.2<br />
<br />
А вот текст .reg файла, которым можно указанный выше путь зарегистрировать в реестре:<br />
<br />
<i><b>Windows Registry Editor Version 5.00</b></i><br />
<b><i><br /></i>
<i>[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Runtime Environment\12.0.2]</i></b><br />
<i><b>"JavaHome"="C:\\openjdk-12.0.2"</b></i><br />
<i><b>"RuntimeLib"="C:\\openjdk-12.0.2\\bin\\server\\jvm.dll"</b></i><br />
<i><b>"MicroVersion"="0"</b></i><br />
<i><b>"BuildNumber"="10"</b></i><br />
<br />
<br />
<i>Насчёт необходимости ключей</i> <i>"MicroVersion"="0", </i><i>"BuildNumber"="10" я не разбирался. Может они не нужны (так выглядит), но OracleJRE их создаёт. Хз, решил, что лучше оставить. Кто знает что в будущем может поломаться из за их отсутствия.</i><br />
<i><br /></i>
<i><br /></i>
<i>ОБНОВЛЕНИЕ:</i><br />
<i><br /></i>
<i>STM32CubeProgrammer </i>не захотел работать с хаком, описаным выше. Как оказалось, CubeProgrammer использует JavaFX, которого нет в официальной сборке OpenJDK. Почему-то за преемлимое время мне не удалось установить OpenJFX поверх OpenJDK, потому я пошёл другим путём и скачал OpenJDK сразу собранный вместе с OpenJFX.<br />
<br />
Скачать можно вот по этой ссылке: <i><a href="https://bell-sw.com/pages/java-13/">https://bell-sw.com/pages/java-13/</a></i><br />
<br />
Архив с этим билдом JDK я распаковал в корень диска C<br />
<br />
А вот контент .reg файла, регистрирующего установку этой версии JDK:<br />
<br />
<i><b>Windows Registry Editor Version 5.00</b></i><br />
<i><b><br /></b></i>
<i><b>[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK]</b></i><br />
<i><b>"CurrentVersion"="13.0.0"</b></i><br />
<i><b><br /></b></i>
<i><b>[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\JDK\10.0.2]</b></i><br />
<i><b>"JavaHome"="C:\\bellsoft-jdk13-windows-amd64\\jdk-13"</b></i><br />
<br />
<br />
Здесь можно заметить, что ветка реестра содержит версию 10.0.2, а не 13.0.0. Это важно, т.к. по этому имени <i>STM32CubeProgrammer </i>проверяет версию java, которая должна быть 1.8.0 - 10.99.99. Приходится таким путём обманывать <i>STM32CubeProgrammer, </i>если хочется иметь в системе свежую версию JDK.</div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-10869915900677788682019-09-02T00:00:00.000+03:002020-02-17T16:09:47.118+03:00Как собирать С++ приложения в Windows C# кодом<div dir="ltr" style="text-align: left;" trbidi="on">
Понадобилось тут собрать С++ Qmake приложение под Windows используя cl компилятор из под C# приложения. При этом хотелось не запускать это C# приложение из под VisualStudio comand prompt, а разрулить всё прямо в коде.<br />
<br />
Обычно, для сборки приложения в консоли студийным компилятором, необходимо открыть VisualStudio command prompt и делать сборку там, либо вручную вызвать vcvars64.bat или vcvarsall.bat для настройки окружения, но тут есть 2 проблемы: 1. Как найти этот bat файл, 2. Как его запустить внутри C# приложения так, что бы он правильно настроил environment variables.<br />
<br />
Решение:<br />
1. Найти все VisualStudio >= 2017 можно при помощи приложения vswhere, которое ставится с VisualStudio installer<br />
2. Находим VisualStudio при помощи vswhere, находим vcvars64.bat, выполняем bat файл, забирая себе его environment в текстовом виде, парсим и применяем в своё приложение.<br />
<br />
<pre class="brush:csharp;">//Find vswhere path
var programFilesDir = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
var vsInstallationDir = Path.Combine(programFilesDir, @"Microsoft Visual Studio", "Installer");
var vsWherePath = Path.Combine(vsInstallationDir, "vswhere.exe");
//Find latest VisualStudio installation directory
var vsWhereResult = SystemProcess.Execute(vsWherePath, "-latest -property installationPath");
var vsInstallPath = vsWhereResult.outBuffer[0];
//Import VisualStudio environment
var vsEnvBatchFile = Path.Combine(vsInstallPath, @"VC\Auxiliary\Build\vcvars64.bat");
var vsEnvResult = SystemProcess.Execute("cmd", $"/C \"{vsEnvBatchFile}\" > nul 2>&1 && set");
Regex envVariableRegex = new Regex("^([^=]+)=(.*)");
foreach(var str in vsEnvResult.outBuffer) {
var match = envVariableRegex.Match(str);
if (match.Success) {
System.Environment.SetEnvironmentVariable(match.Groups[1].Value, match.Groups[2].Value);
}
}
</pre>
В коде вообще нет ни каких проверок, потестил просто как proof of concept. SystemProcess - мой мини враппер над System.Diagnostics.Process, запускает процесс и возвращает массив строк stdout, stderr и exit code.
По хорошему надо делать не совсем так, необходимо применить лишь diff переменных окружения, но в моей задаче это было не нужно.
А дальше просто собираем своё Qmake приложение:
<br />
<pre class="brush:cpp;">//run qmake
SystemProcess.Execute(@"C:\Qt\5.13.0\msvc2019_64_custom\bin\qmake.exe", proFileDir + " -spec win32-msvc \"CONFIG += release\"");
//run nmake
SystemProcess.Execute("nmake");
</pre>
</div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-84119081764199810812018-05-06T23:02:00.006+03:002022-12-04T18:02:57.796+03:00Попиливаю процедурную генерацию геометрии<div dir="ltr" style="text-align: left;" trbidi="on">
Для всякого моего домашнего прототипирования в Unity часто хочется быстро, "вот прям тут", не переключаясь в другую софтину, сгенерировать визуализацию какой-нибудь занятной штуковины, например, 2D функции или же 3D объекта. Сейчас вот использую для визуализации линз оптической системы. Чаще всего это нужно "вот прям тут", т.к. модели параметрические (те же линзы) и на каждое изменение параметров лезть в пакет 3D моделирования и править геометрию - пустая трата времени.<br />
<br />
Использовать готовые решения (даже не искал, знаю только о плагине Houdini для Unity) я, конечно же, не хочу. Так веселее, да и вообще это как отдых ) В большинстве случаев нода процессинга геометрии пишется просто и потому процесс не напряжен, а результат радует.<br />
<br />
Сегодня почти допилил L-System, стараясь косить под Houdini )<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-ECP-VtGZGv8/Wu9egr0FJPI/AAAAAAAAAhs/FPT2KBHRAEgu22r0ASoP3ZYBbJtESLQAQCLcBGAs/s1600/LSystem.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="867" data-original-width="1600" height="352" src="https://1.bp.blogspot.com/-ECP-VtGZGv8/Wu9egr0FJPI/AAAAAAAAAhs/FPT2KBHRAEgu22r0ASoP3ZYBbJtESLQAQCLcBGAs/w651-h352/LSystem.png" width="651" /></a></div>
<br />
<br />
Осталось немного доделать Context matching.<br />
<br />
А вот и хорошая книга по L-системам: <a href="http://algorithmicbotany.org/papers/abop/abop.pdf">The algorithmic beauty of plants</a><br />
<br />
<br />
<br />
<br />
<br />
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-16725926728079011642018-01-22T02:32:00.005+03:002020-02-02T15:19:26.345+03:00PSY-Q SDK (Sony PlayStation1 SDK) на Windows 10 x64<div dir="ltr" style="text-align: left;" trbidi="on">
Для тех, кто уже попробовал запускать программы из <b>PSY-Q SDK</b>, понятно, что этот древний софт ещё не мало проблем принесёт.<br />
<br />
На удивление, компилятор ccpsx оказался 32-битным и спокойно работает в Windows10 x64, чего не скажешь о<b> cpe2x.exe</b> (конвертер .cpe в .exe) и <b>psymake.exe</b> (аналог make), они 16 битные, написаны под DOS, а в Windows x64 NTVDM выпилен, потому приложения запустить невозможно. Видел я, конечно, порты NTVDM под x64, но там встраивание в систему идёт через заднее место и мне это не нравится, тем более они все с жирными пометками "proof of concept".<br />
<br />
Но кто сказал, что это конец? <b>psymake </b>как бы можно вообще выкинуть, заменить его обычным make, например из MinGW! Я решил ради любви к прекрасному оставить таки имя этой утилиты таким, какое оно есть, потому переименовал <b>PSYMAKE.EXE</b> в <b>_PSYMAKE.EXE</b>, вдруг пригодится, а так же вместо него запилил BAT файл <b>PSYMAKE.BAT</b>
<br />
<pre class="brush:cpp;">@echo off
"C:\Program Files\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev1\mingw64\bin\mingw32-make.exe" %*
</pre>
<br />
Теперь при вызове psymake на самом деле перевызывается mingw32-make.exe и всё параметры ему передаются через %*<br />
А вот с cpe2x всё немного сложнее. Я видел его порт под x64, не из оригинальных исходников, а с нуля написанный. И снова у него были какие-то проблемы. Не тру это всё. Есть же рабочее решение, его просто нужно запустить...<br />
<br />
DosBOX - вот кто придёт на помощь. Заменяем <b>CPE2X.EXE</b> на <b>CPE2X.BAT</b> вот примерно с таким контентом
<br />
<pre class="brush:cpp;">@echo off
SET PSYQ_PATH=D:\L\PSOne\psyq
SET DOSBOX_EXE="C:\Program Files (x86)\DOSBox-0.74\DOSBox.exe"
SET SDL_VIDEODRIVER=dummy
REM cleanup CPE2X.EXE stdout file
copy /Y nul: CPE2XOUT.TXT > nul
REM execute CPE2X.EXE inside DOSBOX
%DOSBOX_EXE% -noconsole -c "MOUNT D 'D:\'" -c "D:" -c "cd %cd%" -c "%PSYQ_PATH%\bin\_CPE2X.EXE %* > CPE2XOUT.TXT" -c exit
REM print CPE2X.EXE stdout to console
type CPE2XOUT.TXT
</pre>
<br />
Я тут свои реальные пути в системе оставил, ну да ладно.<br />
Что там происходит:<br />
<br />
1.
<br />
<pre class="brush:cpp;">SET SDL_VIDEODRIVER=dummy</pre>
- т.к. DOSBOX написан с использованием SDL, то есть такой вот легальный путь запустить dosbox в headless режиме!<br />
<br />
2. <br />
<pre class="brush:cpp;">copy /Y nul: CPE2XOUT.TXT > nul</pre>
- тут генерится/очищается файл, который будет содержать в себе выхлоп реального cpe2x.exe, нам же надо всё красиво сделать!<br />
<br />
3. Вызываем DOSBOX! Я монтирую реальный диск D в диск D внутри DOSBOX, так проще работать с путями. Потом переход в папку проекта: -c "cd %cd%" тут важное уточнение: cd указывает на папку проекта, ибо я из неё запускаю данную команду, о том как это делается - напишу ниже. Дальше идёт запуск реального приложения <br />
<pre class="brush:cpp;">"%PSYQ_PATH%\bin\_CPE2X.EXE %* > CPE2XOUT.TXT"</pre>
с перенаправлением вывода в файл, чтоб потом этот файл запринтить хостовому приложению для красоты, типа я запустил настоящее приложение и увидел вывод.<br />
<br />
4. Ну и принтим в консоль вывод<br />
<pre class="brush:cpp;">type CPE2XOUT.TXT</pre>
<br />
С SDK вроде всё.<br />
<br />
Далее внутри проекта прям рядом с сорцами и мейкфайлом я создаю ещё 1 bat файл build_console.bat<br />
<pre class="brush:cpp;">start "PSX Build Console" call "D:\L\PSOne\psyq\PSPATHS.BAT"</pre>
Он мне настраивает пути psy-q и оставляет окно консоли в котором я могу билдить проект! Это удобно!<br />
Внутри окна консоли я просто вбиваю psymake и происходит магия! Всё отлично собирается и даже не видно, что я запускал dosbox!<br />
Вот мой тестовый <b>Makefile</b><br />
<pre class="brush:cpp;">.PHONY: all
all:main.c
ccpsx -O3 -Xo$80010000 main.c -omain.cpe,main.sym,mem.map
cpe2x main.cpe
</pre>
После запуска psymake в этой консоли получаем вот такой красивый вывод:<br />
<pre class="brush:cpp;">D:\L\PSOne\projects\PS1Dev>psymake
ccpsx -O3 -Xo0010000 main.c -omain.cpe,main.sym,mem.map
cpe2x main.cpe
CPE2X Ver1.5
Copyright (C) 1994,1995 by Sony Computer Entertainment Inc.
convert from main.cpe to main.EXE for Japan area
pc0:0000881c t_addr:00002710 t_size:00008800
</pre>
</div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-80121115606507256982018-01-08T01:14:00.000+03:002018-05-06T01:49:30.484+03:00Ретро задротство: запилил диски для PlayStation 1<div dir="ltr" style="text-align: left;" trbidi="on">
Еле нашёл нормальные Jewel box-ы для дисков в Воронеже (не удивительно, время дисков уже прошло)! Китайцы же вообще обалдели, продают по цене от 140р за ОДНУ коробку!!! Ну да ладно, это как с биткоинами - главное вовремя закупиться ) Ах да, купил я эти коробки в классном магазинчике "Темп" на Плехановской, вот: <a href="https://goo.gl/maps/MUTooGEchcH2">https://goo.gl/maps/MUTooGEchcH2</a> <br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-8IE12ijbA-4/WlKawGiDpAI/AAAAAAAAAfU/B696vlF9jysKsWWoEW6oZAOXE52VksJyQCLcBGAs/s1600/20180103_172212.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1024" height="300" src="https://1.bp.blogspot.com/-8IE12ijbA-4/WlKawGiDpAI/AAAAAAAAAfU/B696vlF9jysKsWWoEW6oZAOXE52VksJyQCLcBGAs/s400/20180103_172212.jpg" width="400" /></a></div>
<br />
<br />
Потом разобрался с размерами печати, запилил разметку в фотошопе и нагенерил кучу обложек, распечатал, вырезал, вставил в диски и вот...<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-BON2V9RI8FI/WlKbL2P-YqI/AAAAAAAAAfY/An8CwN_zsIoNGgF0tCI07xuSYGLvvVEgQCLcBGAs/s1600/20180103_202808.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://3.bp.blogspot.com/-BON2V9RI8FI/WlKbL2P-YqI/AAAAAAAAAfY/An8CwN_zsIoNGgF0tCI07xuSYGLvvVEgQCLcBGAs/s640/20180103_202808.jpg" width="640" /></a></div>
<br />
<br />
И вот<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-jg2K6fYdoZA/WlKbeBQs4wI/AAAAAAAAAfc/L1DJN77JVRU6sYA1hInCNFIvdLIlRBHXQCLcBGAs/s1600/20180103_202856.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://4.bp.blogspot.com/-jg2K6fYdoZA/WlKbeBQs4wI/AAAAAAAAAfc/L1DJN77JVRU6sYA1hInCNFIvdLIlRBHXQCLcBGAs/s640/20180103_202856.jpg" width="640" /></a></div>
<br />
<br />
<br />
И вот<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-DlSf7MqnJ70/WlKbtBkqyzI/AAAAAAAAAfg/lk0L7Zgw4VQciNEq6dWiuJB6bZ6Y13HfQCLcBGAs/s1600/20180105_122041.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1024" height="480" src="https://3.bp.blogspot.com/-DlSf7MqnJ70/WlKbtBkqyzI/AAAAAAAAAfg/lk0L7Zgw4VQciNEq6dWiuJB6bZ6Y13HfQCLcBGAs/s640/20180105_122041.jpg" width="640" /></a></div>
<br />
<br />
Сделал те же диски, что когда-то раньше и были у меня, но давно утеряны.<br />
<span id="goog_588691720"></span><span id="goog_588691721"></span></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0Воронеж, Воронежская обл., Россия51.6754966 39.20888230000002751.0455641 37.917988800000025 52.305429100000005 40.49977580000003tag:blogger.com,1999:blog-824665217355978368.post-53108676471281341962018-01-08T00:52:00.000+03:002018-01-08T16:05:30.047+03:00Ретро задротство: пишем простое приложение для PlayStation 1<div dir="ltr" style="text-align: left;" trbidi="on">
Наконец дошли руки и я таки выполнил одно из древних желаний - написал хоть какой-то рабочий код для PlayStation1 !!<br />
<br />
Буду иногда тут исследовать PS1 SDK (Psy-Q) <a href="https://github.com/L-proger/PS1Dev">https://github.com/L-proger/PS1Dev</a><br />
<br />
Понял как выводится дефолтный текст (шрифт грузится из BIOS-а), очищается экран (можно просто очистить через GsClearDispArea или закинуть вместе с другими задачами через GsSortClear).<br />
<br />
Курить ещё много чего надо, документация в SDK очень корявая и конечно же ни каких примеров в ней, благо есть демки в интернете, в них можно подсмотреть код )<br />
<br />
Нашёл ещё крутейший эмулятор, no$psx: <a href="http://problemkaputt.de/psx.htm">http://problemkaputt.de/psx.htm</a> Он единственный (из всех что я видел) имеет дебаггер с breakpoint-ами и главное (для меня) умеет выводить в окно результат printf!!! Дада, в ps1 был дебаг порт куда можно было принтить.<br />
<br />
А вот и скрин (собрал диск .iso, запустил в эмуляторе, прожигать на болванку пока лень).<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-MnMNx5JuRYQ/WlKVFSFMyMI/AAAAAAAAAfQ/3nxtaZ0kyo4NbL6UqVpxTY2Y4tbw5J3_ACLcBGAs/s1600/PS1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="507" data-original-width="642" height="504" src="https://3.bp.blogspot.com/-MnMNx5JuRYQ/WlKVFSFMyMI/AAAAAAAAAfQ/3nxtaZ0kyo4NbL6UqVpxTY2Y4tbw5J3_ACLcBGAs/s640/PS1.png" width="640" /></a></div>
<br />
<br />
<br />
Если не извращаться и юзать всё как есть в SDK, то необходимо поставить Windows x86 (обязательно, в x64 не запускаются тулзы из SDK), не новее Windows 7. Собственно, я и поставил Windows7 x86 в виртуалку, в ней и делаю сборку. Однако, программирую в своей хостовой OS Windows 10 в VisualStudio. Открываю проект-папку, в json прописаны пути инклудов и вуаля, годная IDE, комплит и OS в виртуалке только ради сборки.</div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-66524470690177463292017-09-25T17:09:00.000+03:002017-09-25T17:12:33.970+03:00STM32 HAL_SPI_TransmitReceive_DMA restart bug<div dir="ltr" style="text-align: left;" trbidi="on">
Захотелось мне перезапустить трансфер SPI прямо в колбэке <i>HAL_SPI_TxRxCpltCallback</i>. Казалось бы, из названия колбэка ясно, что вызывается он, когда <b>и</b> Tx <b>и</b> Rx полностью завершены и нет причин, почему в этом же колбэке нельзя запустить новый трансфер.<br />
<br />
А вот и есть: рукожопость. Если внутри <i>HAL_SPI_TxRxCpltCallback</i> снова вызвать <i>HAL_SPI_TransmitReceive_DMA</i>, то трансфер никогда не завершится.<br />
<br />
А вот почему? Изначально не понятно, я же хорошо написал код, захендлил все Error code-ы библиотеки и если что-то не так, то я бы увидел в терминале ошибку и код автоматом бы мне вызвал breakpoint. Но всё вроде как ок, ошибок нет!<br />
<br />
Проверил под дебаггером - да, HAL_SPI_TransmitReceive_DMA во второй раз возвращает HAL_OK! Статусы/регистры все сконфигурены корректно в SPI, стейт BUSY но прерываний нет... о_О<br />
<br />
Но не стоит недооценивать разработчиков HAL библиотеки, они те ещё рукожопы. Вспомнил я как несколько лет назад писал им в саппорт и уведомлял о баге, но конечно же его не починили )<br />
<br />
<i>Часть кода функции HAL_SPI_TransmitReceive_DMA:</i><br />
<br />
<pre class="brush:cpp;">
/* Set the DMA AbortCpltCallback */<br />
hspi->hdmarx->XferAbortCallback = NULL;<br />
/* Enable the Rx DMA Stream/Channel */<br />
HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, hspi->RxXferCount);<br />
/* Enable Rx DMA Request */<br />
SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);<br />
</pre>
<br />
<br />
HAL_DMA_Start_IT возвращает код ошибки, который благополучно игнорируется! И кажется, что всё ОК )) А на самом деле HAL_SPI_TxRxCpltCallback вызывается из прерывания RX DMA канала, а обработчик TX канала ещё не вызывался к этому моменту (он вызовется <b>после </b>RX канала). И получается, что в колбэке RX DMA канала я перезапускаю передачу, которая не смогла запустить TX DMA канал (он ещё не разлочен своим обработчиком прерывания) и потому всё висит.<br />
<br />
Это восхитительно. Мало того, что TX прерывания ещё не было, но уже вызвался HAL_SPI_TxRxCpltCallback , так ещё и коды ошибок нагло игнорируются, вводя в глубочайшее заблуждение. Вот как так? Железо у ST отличное, а код - говно...<br />
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-1780735799192121562017-08-01T13:09:00.001+03:002017-08-06T13:27:42.450+03:00Программирование и отладка NRF52 под ST-LinkV2<div dir="ltr" style="text-align: left;" trbidi="on">
NRF52 - ARM v7 микроконтроллеры от Nordic Semiconductor со встроенным радио (bluetooth, кастомные протоколы, 2.4 GHz). <br />
<br />
Официально программирование/отладка поддерживается хорошо лишь с J-Link, но он стоит в районе 500$, а прям ощутимого профита от его использования я особо не заметил ) Так зачем платить больше? По крайней мере для домашних проектов...<br />
<br />
На текущий момент в OpenOCD 0.10 нет драйвера флеш-памяти для NRF52, потому "из коробки" будет доступна только отладка, а стирание/прошивание чипа - нет.<br />
<br />
К счастью имеется уже готовый патч для OpenOCD, а так же инструкция как что собирать, которую я нашёл вот в <a href="https://devzone.nordicsemi.com/question/78890/programming-nrf52-with-openocd/?answer=82859#post-id-82859">этом обсуждении</a>.<br />
<br />
На всякий пожарный повторю здесь инструкции + дополню своими:
<br />
<br />
Для начала при сборке в Windows придётся поставить кросс компилер, например, из msys или cygwin. Я предпочитаю mingw-w64 для x64 системы из msys, <a href="https://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29/">скачать можно тут</a>.<br />
<br />
Запускаем mingw64.exe, ставим зависимости и инструменты, необходимые для сборки. Точный список уже не помню, но как минимум это я ставил:
<br />
<br />
<pre class="brush:cpp;">pacman -S git
pacman -S curl
pacman -S make
pacman -S automake
pacman -S autoconf
pacman -S libtool
pacman -S pkg-config
pacman -S texinfo
pacman -S mingw-w64-x86_64-toolchain
pacman -S mingw64/mingw-w64-x86_64-dlfcn
pacman -S mingw64/mingw-w64-x86_64-libusb
pacman -S mingw64/mingw-w64-x86_64-libusb-usbdk
pacman -S mingw64/mingw-w64-x86_64-hidapi
pacman -S mingw64/mingw-w64-x86_64-libftdi
</pre>
<br />
Клонируем репозиторий:<br />
<br />
<pre class="brush:cpp;">git clone git://git.code.sf.net/p/openocd/code openocd-code
cd openocd-code
</pre>
<br />
Теперь необходимо применить патч, добавляющий поддержку NRF52. Однако я бы порекомендовал файл <b>src/flash/nor/Makefile.am</b> предварительно забэкапить )<br />
<br />
<pre class="brush:cpp;">git pull http://openocd.zylin.com/openocd refs/changes/15/3215/2
</pre>
<br />
Патч приводит к конфликтам в двух файлах, конфликты можно просто поправить вручную. Суть конфликта - в каждом из файлов добавляется инклуд NRF52 сорцов, однако порядок строк инклудов изменён и получается странный конфликт.
<br />
<br />
<pre class="brush:cpp;">
gedit src/flash/nor/drivers.c
gedit src/flash/nor/Makefile.am
</pre>
Во втором файле ещё и формат путей инклудов поменялся, потому там вообще ад, и как раз для этого я выше рекомендовал <b>src/flash/nor/Makefile.am</b> забэкапить, после чего его восстановить и вручную прописать инклуд NRF52. То есть к NOR_DRIVERS добавить файл <b>%D%/nrf52.c \</b> и это всё, что там надо поменять.<br />
<br />
Следующий шаг:<br />
<pre class="brush:cpp;">./bootstrap
</pre>
После чего настраиваем сборку:
<br />
<pre class="brush:cpp;">./configure \
--prefix=/Your-path/openocd-git_install \ //Заменить на свой путь утановки
--enable-aice \
--enable-amtjtagaccel \
--enable-armjtagew \
--enable-cmsis-dap \
--enable-dummy \
--enable-ftdi \
--enable-gw16012 \
--enable-jlink \
--enable-jtag_vpi \
--enable-opendous \
--enable-openjtag_ftdi \
--enable-osbdm \
--enable-legacy-ft2232_libftdi \
--enable-parport \
--disable-parport-ppdev \
--enable-parport-giveio \
--enable-presto_libftdi \
--enable-remote-bitbang \
--enable-rlink \
--enable-stlink \
--enable-ti-icdi \
--enable-ulink \
--enable-usb-blaster-2 \
--enable-usb_blaster_libftdi \
--enable-usbprog \
--enable-vsllink
</pre>
И собираем проект:
<br />
<pre class="brush:cpp;">make
make install
</pre>
Готово, OpenOCD собран. Теперь, для запуска его без предварительного добавления mingw директорий в PATH, необходимо рядом с OpenOCD.exe положить dll, от которых он зависит:
<br />
<pre class="brush:cpp;">libftdi1.dll
libhidapi-0.dll
libusb-0-1-4.dll
libusb-1.0.dll
</pre>
Найти их все можно в папке <b>msys64\mingw64\bin</b>
<br />
<br />
И казалось бы всё, готово, можно пользоваться. Да, но <i>почти </i>) OpenOCD запускается и прекрасно себя чувствует, однако при попытке отладки любого st-link устройства каждый раз получаю ошибку:
<br />
<br />
<pre class="brush:cpp;">stlink_usb_open(): stlink_usb_open
stlink_usb_open(): transport: 1 vid: 0x0483 pid: 0x374b serial:
stlink_usb_open(): open failed
</pre>
<pre class="brush:cpp;"></pre>
Долго я думал что не так! И сорцы OpenOCD пытался править и очередные баги в исходниках libusb искать, но решил в итоге проблему намного проще )) Качаем бинарники libusb <a href="https://sourceforge.net/projects/libusb/files/libusb-1.0/"> https://sourceforge.net/projects/libusb/files/libusb-1.0/</a><br />
<br />
Заменяем корявую libusb-1.0.dll, взятую из mingw64, на нормальную из архива MinGW64\dll\libusb-1.0.dll и всё, программатор открывается.<br />
<br />
Пример *.cfg файла для OpenOCD
<br />
<br />
<pre class="brush:cpp;">source [find interface/stlink-v2.cfg]
transport select "hla_swd"
source [find target/nrf52.cfg]
</pre>
</div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-48683213446997893092017-08-01T03:13:00.003+03:002017-08-01T03:26:46.677+03:00Новая железка<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: left;">
Прикупил вот в Китае для всяческих экспериментов поворотную платформу с 2 степенями свободы. <a href="https://ru.aliexpress.com/item/Official-smarian-2-DOF-All-Metal-Rotation-Base-Platform-for-Robot-Arm-with-2pcs-High-Torque/32793398433.html">https://ru.aliexpress.com/item/Official-smarian-2-DOF-All-Metal-Rotation-Base-Platform-for-Robot-Arm-with-2pcs-High-Torque/32793398433.html</a> Интересная и относительно недорогая штука.</div>
<br />
Основной подшипник не люфтит (по ощущениям, замерить нечем), редукторы сервоприводов сделаны из металлических шестерёнок (выбрал по ссылке самые простые движки), вся конструкция металлическая (кроме нижней здоровой площадки, к счастью).<br />
<br />
Занятно, что ни у одного продавца на aliexpress, а также на сайте производителя <a href="http://makerobotix.com/">http://makerobotix.com</a> я так и не нашёл мануала по сборке и в итоге потратил час на скручивание всех деталей вместе.<br />
<br />
Болтов и гаек продавец не пожалел, видимо в курсе канона, что после сборки просто обязаны остаться "лишние детали" )<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-cIb06-MQ8og/WX_E4J03DCI/AAAAAAAAAdQ/bX2sT7-OGwo_BPLdHQvbsZkTxzvn2DU9gCLcBGAs/s1600/WP_20170731_23_08_19_Raw_1280.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1280" height="360" src="https://1.bp.blogspot.com/-cIb06-MQ8og/WX_E4J03DCI/AAAAAAAAAdQ/bX2sT7-OGwo_BPLdHQvbsZkTxzvn2DU9gCLcBGAs/s640/WP_20170731_23_08_19_Raw_1280.jpg" width="640" /></a></div>
<br />
<br />
Два диска хватаются за внутреннее кольцо подшипника с двух сторон и два металлических кольца за внешнюю оболочку.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-h0QYW2eLCoU/WX_Fr3yb6II/AAAAAAAAAdU/kwyGK3ZVF_kPRYwqgoaDzt4yP-HHsbTxgCLcBGAs/s1600/WP_20170801_00_29_10_Raw_1280.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1280" height="360" src="https://2.bp.blogspot.com/-h0QYW2eLCoU/WX_Fr3yb6II/AAAAAAAAAdU/kwyGK3ZVF_kPRYwqgoaDzt4yP-HHsbTxgCLcBGAs/s640/WP_20170801_00_29_10_Raw_1280.jpg" width="640" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://3.bp.blogspot.com/-zl9ab1QdOXw/WX_F_-2IaDI/AAAAAAAAAdY/anM9tG6L_k0frfTyecBr3rieaPfkUFFtACLcBGAs/s1600/WP_20170801_01_12_10_Raw_1280.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1280" height="360" src="https://3.bp.blogspot.com/-zl9ab1QdOXw/WX_F_-2IaDI/AAAAAAAAAdY/anM9tG6L_k0frfTyecBr3rieaPfkUFFtACLcBGAs/s640/WP_20170801_01_12_10_Raw_1280.jpg" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-N9Q-7OX7Y9c/WX_F_yZBI-I/AAAAAAAAAdc/NkZnhyZMxpkPqMCC0olotMFw4QeSlqlhQCLcBGAs/s1600/WP_20170801_01_12_46_Raw_1280.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1280" height="360" src="https://2.bp.blogspot.com/-N9Q-7OX7Y9c/WX_F_yZBI-I/AAAAAAAAAdc/NkZnhyZMxpkPqMCC0olotMFw4QeSlqlhQCLcBGAs/s640/WP_20170801_01_12_46_Raw_1280.jpg" width="640" /></a></div>
<br />
При сборке важно не забывать, что у подобных сервоприводов угол поворота всего 180 градусов! Потому надо прикручивать кронштейн так, чтоб он мог повернуться в любую ему доступную позицию. Для этого можно сначала аккуратно провернуть вал движка (не слишком насилуя редуктор) и нащупать где у него граница поворота.<br />
<br />
На пустое место нижней акриловой площадки можно будет удобно установить управляющую плату. Правда, мне до получения посылки хотелось и верилось, что девайс будет скромнее в размерах )<br />
<br />
Ну и "лишние детали" после сборки:<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://1.bp.blogspot.com/-fHWCWqA2960/WX_HpIuE-UI/AAAAAAAAAdg/BPR_CPRtbi4PbfYJlRZp98-vMl4QMfRAwCLcBGAs/s1600/WP_20170801_01_11_06_Raw.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="360" src="https://1.bp.blogspot.com/-fHWCWqA2960/WX_HpIuE-UI/AAAAAAAAAdg/BPR_CPRtbi4PbfYJlRZp98-vMl4QMfRAwCLcBGAs/s640/WP_20170801_01_11_06_Raw.jpg" width="640" /></a></div>
<br />
<br />
<br />
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-72930412976984782602017-03-11T01:23:00.002+03:002017-04-05T02:38:05.527+03:00Как убить материнскую плату за полчаса (перепаивание AMD GPU)<div dir="ltr" style="text-align: left;" trbidi="on">
<b>Дано:</b><br />
1. Материнская плата ноутбука HP Pavilion DV6 6179er со сгоревшим GPU чипом.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-eba6-0cQohs/WMMhcqHaewI/AAAAAAAAAbs/E9mPMVUJa3oJiw0_1Uqro965akd9wRiNwCLcB/s1600/WP_20161230_17_29_31_Pro_222.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="398" src="https://2.bp.blogspot.com/-eba6-0cQohs/WMMhcqHaewI/AAAAAAAAAbs/E9mPMVUJa3oJiw0_1Uqro965akd9wRiNwCLcB/s640/WP_20161230_17_29_31_Pro_222.jpg" width="640" /></a></div>
<br />
2. Свежекупленный GPU чип на aliexpress<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-7tYDA8vaBzA/WMMgpp63WlI/AAAAAAAAAbk/-h6m6312tiI44OAf9Phl7PBKmj8nsHhCwCLcB/s1600/WP_20161230_15_04_06_Pro2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="500" src="https://2.bp.blogspot.com/-7tYDA8vaBzA/WMMgpp63WlI/AAAAAAAAAbk/-h6m6312tiI44OAf9Phl7PBKmj8nsHhCwCLcB/s640/WP_20161230_15_04_06_Pro2.jpg" width="640" /></a></div>
<br />
3. Паяльная станция, годный флюс, термоскотч, энтузиазм, ноль опыта в подобных манипуляциях.<br />
<br />
<b>Задача:</b> перепаять GPU чип.<br />
<br />
<b>Приступим:</b><br />
<br />
1. Мощно обклеим всю материнскую плату (исключая видео чип) термоскотчем для защиты от перегрева (на самом деле столько скотча не нужно, просто мне понравилось обклеивать), густо нанесём хороший флюс вокруг чипа (при нагревании он затекает под чип и вроде как лучше проводит тепло), сделаем красивое фото.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-b00ljGpf4DM/WMMiThvDHKI/AAAAAAAAAb0/4sncoK-1o88mnRFJ3Nppv9d936hzM3hkwCLcB/s1600/WP_20161230_18_00_26_Pro_222.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="366" src="https://2.bp.blogspot.com/-b00ljGpf4DM/WMMiThvDHKI/AAAAAAAAAb0/4sncoK-1o88mnRFJ3Nppv9d936hzM3hkwCLcB/s640/WP_20161230_18_00_26_Pro_222.jpg" width="640" /></a></div>
<br />
<br />
2. Потихоньку прогреваем паяльным феном видео чип до 330 градусов.<br />
3. Что-то не так, 330 градусов "как обычно", но чип недвижим.<br />
4. Греем до 400 градусов - ноль реакции<br />
5. Греем с ужасом до 430 градусов - начинает плавиться термоскотч и жутко вонять, чип недвижим о_О<br />
6. Греем до 450 градусов - чип начинает двигаться. Здесь очень важно не прекращать ни в коем случае нагрев и не прикладывать ощутимых усилий в попытках сдвинуть чип. Лучше всего его поднимать вакуумным пинцетом, что я понял гораздо позже (. Если в процессе снятия чипа немного снизится температура, то он тут же обратно припаивается, да ещё и очень криво. Обратное припаивание в процессе снятия чипа может привести к тому, что можно сорвать площадки, к которым чип припаян. Они <b>ОЧЕНЬ </b>легко отрываются, тем более когда так жутко перегрета плата.<br />
7. Снимаем чип (аккуратно, <b>без усилий!!!). </b>Тут ещё один важный момент есть: вокруг чипа напаяна куча SMD компонентов и снимая его пинцетом можно случайно толкнув сдвинуть эти самые SMD компоненты, потому куда приятнее поднимать его вакуумным пинцетом сразу вертикально.<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<b><br /></b>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-2acqEka9bpo/WMMkvvm3r7I/AAAAAAAAAcE/S0lRymuYhoczdPKsG0-wuxTMwu-BOVweQCLcB/s1600/WP_20161230_18_18_49_Pro222.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="https://4.bp.blogspot.com/-2acqEka9bpo/WMMkvvm3r7I/AAAAAAAAAcE/S0lRymuYhoczdPKsG0-wuxTMwu-BOVweQCLcB/s640/WP_20161230_18_18_49_Pro222.jpg" width="640" /></a></div>
<br />
8. На падах осталось много олова (или стали, WTF, почему у этого сплава температура плавления 450 градусов???), необходимо удалить всё <b>аккуратно </b>(о, да :(( ) и качественно, иначе чип плохо припаяется. Берём специальную оплётку, паяльник (и как я <i>тупим дико</i> и <i>убираем подогрев феном</i>, надеясь на паяльник), обильно смазываем флюсом и чистим пады.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://2.bp.blogspot.com/-20Iq4lvNVm8/WMMltUl0x_I/AAAAAAAAAcM/iWw9czBVFvwE8tYzrCnVlzIRKRIcQ3wMgCLcB/s1600/WP_20161230_18_25_05_Pro222.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="368" src="https://2.bp.blogspot.com/-20Iq4lvNVm8/WMMltUl0x_I/AAAAAAAAAcM/iWw9czBVFvwE8tYzrCnVlzIRKRIcQ3wMgCLcB/s640/WP_20161230_18_25_05_Pro222.jpg" width="640" /></a></div>
<br />
9. Ну вот и всё, осталось впасть в уныние и печалиться с того, что не подумал вовремя, убрал подогрев (мешался), попытался при помощи оплётки и паяльника снять олово и оторвал несколько падов. Оплётка довольно большая, паяльник не очень мощный и часто во время движения оплётки по площадкам паяльник не догревает, олово резко остывает и по инерции лёгким движением руки срываются с платы тоненькие площадки.<br />
<br />
Если приглядеться, можно заметить на фото оторванные площадки по краям (те, что поменьше)<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-5X81GvvJalg/WMMnaD1ScWI/AAAAAAAAAcY/W_uzA6uOPEkYJ-ECTLVtIn5ZeZbFg9ANQCLcB/s1600/WP_20170125_23_49_43_Pro333.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="560" src="https://4.bp.blogspot.com/-5X81GvvJalg/WMMnaD1ScWI/AAAAAAAAAcY/W_uzA6uOPEkYJ-ECTLVtIn5ZeZbFg9ANQCLcB/s640/WP_20170125_23_49_43_Pro333.jpg" width="640" /></a></div>
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com2tag:blogger.com,1999:blog-824665217355978368.post-15351683168977085852016-11-29T12:54:00.000+03:002016-12-25T22:23:51.870+03:00Проблемы с File URI SVN в Linux после Windows<div dir="ltr" style="text-align: left;" trbidi="on">
Ситуация такова: в локальной сети имеется компьютер с именем, например, server. На нём расшарена папка с именем svn в которой я храню свои SVN репозитории. На том компе нет реального "SVN сервера", просто расшареная виндовая (samba) сетевая папка, в которой вручную создаются репозитории (каждый в своей подпапке).<br />
<br />
Как чекаютятся репозитоии в windows в таком случае: используется file схема пути, т.е. например file://server/svn/MyProject и всё работает отлично.<br />
<br />
И вот настал тот час, когда мне стало необходимо зачекаутить этот репозиторий и из под Linux-а. Тут ждёт первая проблема: file схема на линуксе работает только с локальными путями! Все остальные требуют сервера на удалённом компьютере (что у меня сейчас не возможно). Первое решение очевидное - просто монтируем сетевую папку например в /mnt/svn и оттуда чекаутим file:///mnt/svn/MyProject и это действительно отлично работает! Кроме одного косяка... Работая под Windows-ом в репозиторий MyProject я добавил внешний (external) репозиторий MyProject2! И конечно же до него путь сохранился такой: file://server/svn/MyProject2 и при чекауте MyProject SVN не может слить его зависимость по пути <i>file://server/svn/MyProject2</i>.<br />
<br />
То есть по хорошему у меня должен работать чекаут точно по тем же путям, что и в windows, что проблематично, но не возможного же не бывает...<br />
<div>
<br /></div>
<div>
Первое действие - создал в корне файловой системы папку /svn и примонтировал в неё сетевую папку server/svn. Всё ок, я могу чекаутить мой проект по пути file:///svn/MyProject Теперь на хватает в пути всего-то слова server. К счастью в svn есть один альтернативный вариант написания пути: file://localhost/svn/MyProject. Однако проблема в том, что на линуксе SVN <i>просто удаляет</i> слово <i>localhost </i>из пути! И если оно написано не верно, то выводит ошибку и ни чего не делает. Плохо, что нет резолва IP и чекаута по сети и слово localhost - просто затычка, однако в моём простом случае это и было решением )<br />
<br />
Так как localhost просто заглушка и ни чего не значит, то его можно заменить и на другое слово, например... на слово "server" ) Беда только в том, что внешних конфигов нет, это слово зашито в коде SVN. Но разве ж это настоящая проблема?<br />
<br />
Решение: <br />
<div>
<div style="text-align: left;">
1. Чекаут исходников subversion <i><b>svn co http://svn.apache.org/repos/asf/subversion/trunk subversion</b></i></div>
2. Идём в папку<b> subversion/subversion/libsvn_subr</b>, открываем файл <b>dirent_uri.c</b><br />
3. Находим функцию <b>svn_uri_get_dirent_from_file_url</b><br />
4. Ищем код
<br />
<pre class="brush:cpp;">if (strcmp(hostname, "localhost") == 0)
hostname = NULL;
</pre>
5. меняем на такой код
<br />
<pre class="brush:cpp;">if (strcmp(hostname, "localhost") == 0 || strcmp(hostname, "server") == 0)
hostname = NULL;
</pre>
6. Билдим SVN <br />
<pre class="brush:cpp;">
sudo apt-get install autoconf
sudo apt-get install libtool-bin
sudo apt-get install apache2-dev libapr1-dev libaprutil1-dev
sudo apt-get install zlib1g-dev
./get-deps.sh
cd apr/
./buildconf
cd ../apr-util/
./buildconf
cd ../apr-util/xml/expat/
./buildconf.sh
cd ../../..
./autogen.sh
./configure
make //в папке subversion
</pre>
7. Устанавливаем в систему
В папке <b>subversion/subversion/svn</b> лежит бинарник с именем <b>svn </b>Я его просто копировал в /usr/bin
Но может ещё понадобиться сделать
<br />
<pre class="brush:cpp;"> sudo make install
</pre>
Иначе некоторые зависимости не находит! Почему make install не ставит сам бинарник (у меня) - не ясно, курить скрипты лень )
</div>
</div>
</div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-45954089259123243992016-09-10T02:48:00.002+03:002016-09-10T10:23:48.857+03:00D3D12<div dir="ltr" style="text-align: left;" trbidi="on">
Решил поломать код движка, да перевести на DX12. На удивление туго пошло осознание нового АПИ, пришлось потратить 4 вечера на минимальный порт. А вот и свежие восхитительные пиксели, отрендеренные на D3D12:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-B-y6cJtlkTQ/V9NKQGpQn8I/AAAAAAAAAao/VLPqGo24zh0lugcVH41vRiimaKLrccsvwCLcB/s1600/dx12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="510" src="https://4.bp.blogspot.com/-B-y6cJtlkTQ/V9NKQGpQn8I/AAAAAAAAAao/VLPqGo24zh0lugcVH41vRiimaKLrccsvwCLcB/s640/dx12.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Отличная серия уроков по D3D12: <a href="http://www.braynzarsoft.net/viewtutorial/q16390-setting-up-directx-12-for-visual-studio-2015">http://www.braynzarsoft.net/viewtutorial/q16390-setting-up-directx-12-for-visual-studio-2015</a></div>
</div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-56434970517902434602016-06-12T17:34:00.003+03:002016-06-13T10:00:03.611+03:00Работа с EEPROM 24C16 на STM32 контроллере<div dir="ltr" style="text-align: left;" trbidi="on">
Понадобилось по-быстрому запилить простой "программатор" EEPROM микросхемы, да чтоб читать/писать память её можно было через юзерское приложение в Windows. И что-то я подзатупил изначально с адресацией памяти. <br />
<br />
Для работы с EEPROM (и не только) в STM32CubeF4 библиотеке есть функции <b>HAL_I2C_Mem_Read </b>и <b>HAL_I2C_Mem_Write</b>, инициализацию I2C генерит приложение STM32CubeMX, в общем-то халява, осталось использовать функции, передать данные из/в компьютер и девайс готов. Однако меня сбил с толка параметр функций <b>uint16_t MemAddSize, </b>который может быть равен <b>I2C_MEMADD_SIZE_8BIT </b>или <b>I2C_MEMADD_SIZE_16BIT.</b> В моей микросхеме 2048 байт памяти и логично предположить, что мне нужен вариант <b>I2C_MEMADD_SIZE_16BIT, </b>т.е. 16 бит на адрес,ибо 8 бит хватит только на адресацию 256 байт.<br />
<br />
<br />
А вот и нет. Память "побита" на блоки по 256 байт, выбор ID блока происходит через запись соответствующего ID в биты 1,2,3 байта адреса устройства:<br />
<br />
<a href="https://4.bp.blogspot.com/-G9oW25307q8/V11yHqBHzHI/AAAAAAAAAZ4/UC5Rq79aHoEgegTGislpVjXXj7DnMLMwgCLcB/s1600/eeprom_table.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="116" src="https://4.bp.blogspot.com/-G9oW25307q8/V11yHqBHzHI/AAAAAAAAAZ4/UC5Rq79aHoEgegTGislpVjXXj7DnMLMwgCLcB/s640/eeprom_table.png" width="640" /></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Их можно трактовать как ID 256-байтного блока или просто как старшие дополнительные 3 бита адреса памяти (как в таблице и указано). То есть адресация здесь 11 битная.<br />
<br />
Собственно, адрес _устройства_ получаем таким образом: <b>0xA0 | ((memory_address >> 7) & 0xE)</b>. Нулевой бит по идее контроллируется библиотекой и делать операцию битового чтения & 0xF по идее не нужно. Но опыт подсказывает, что доверять библиотеке Cube от ST не стоит )<br />
<br />
Вдруг кому сэкономит время )</div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com4tag:blogger.com,1999:blog-824665217355978368.post-60125704943784002842016-04-09T18:03:00.001+03:002016-04-09T18:23:30.185+03:00HDMI на FPGA Cyclone II<div dir="ltr" style="text-align: left;" trbidi="on">
Запилил на своём борде с Cyclone II генерацию HDMI сигнала. Всё сделано так же как и в проекте <a href="https://marsohod.org/plata-marsokhod3/proekty-dlya-platy-marsokhod3/307-max10-hdmi">HDMI для платы Марсоход3</a>, только у меня разрешение картинки 800x600x60Hz<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://4.bp.blogspot.com/-Wk1FhlFmPEE/VwkZygbenqI/AAAAAAAAAZc/jS8ugnFN1VwogCou2fzkvVyRjvu6qnDiw/s1600/WP_20160409_17_54_19_Pro.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="476" src="https://4.bp.blogspot.com/-Wk1FhlFmPEE/VwkZygbenqI/AAAAAAAAAZc/jS8ugnFN1VwogCou2fzkvVyRjvu6qnDiw/s640/WP_20160409_17_54_19_Pro.jpg" width="640" /></a></div>
<br />
Для генерации разрешения 800x600 необходимо во-первых заменить параметры таймингов в файле HDMI_1280.v на эти<br />
<br />
<i>always @(posedge pixclk) DrawArea <= (CounterX<800) && (CounterY<600); </i><br />
<i>always @(posedge pixclk) CounterX <= (CounterX==1055) ? 0 : CounterX+1; </i><br />
<i>always @(posedge pixclk) if(CounterX==1055) CounterY <= (CounterY==627) ? 0 : CounterY+1;</i><br />
<i>always @(posedge pixclk) hSync <= (CounterX>=840) && (CounterX<968);</i><br />
<i>always @(posedge pixclk) vSync <= (CounterY>=601) && (CounterY<605);</i><br />
<i><br /></i>
<i>А так же сгенерить свою PLL с 2 выходами клоков на 40MHz и на 200MHz. 40MHz - частота тактования пикселей, с ней всё ясно, а вот 200 MHz это частота тактования TMDS энкодеров (в HDMI применяется TMDS 10 битное кодирование), они тактоваться должны на частоте в 10 раз быстрее пиксельклоков, однако т.к. используются DDR выходы ПЛИС-а, частота тактования TMDS делится на 2, итого (40*10)/2 = 200MHz</i></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-67014892036077074452016-01-07T18:20:00.002+03:002016-01-07T20:13:36.755+03:00Симулятор квадрокоптера: симуляция щёточных DC моторов<div dir="ltr" style="text-align: left;" trbidi="on">
Решил немного поразвлечься и запилить симуляцию щёточных моторов постоянного тока в Unity для виртуального квадрокоптера и не только.<br />
<br />
Не думал о подобном ранее, но чуток покопавшись понял, что всё достаточно просто )<br />
(Я далеко не физик/электронщик и могу что-то сам не так понимать или описывать, но тем не менее)<br />
<br />
Щёточный DC схематически можно представить так:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-L_aDPrvZjoE/Vo51Bh4_OFI/AAAAAAAAAX4/Owb_PDNpdjQ/s1600/motor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="209" src="http://3.bp.blogspot.com/-L_aDPrvZjoE/Vo51Bh4_OFI/AAAAAAAAAX4/Owb_PDNpdjQ/s320/motor.png" width="320" /></a></div>
<br />
<br />
<br />
R - сопротивление обмотки ротора.<br />
L - индуктивность обмотки ротора<br />
e - обратная ЭДС обмоток ротора.<br />
J - момент инерции ротора<br />
<br />
Из за вращения ротора в статичном магнитном поле в его обмотках появляется обратная ЭДС, создающая обратное напряжение в обмотках, которое ограничивает максимальные обороты движка (но не только оно ограничивает). Зависит линейно от угловой скорости ротора.<br />
<br />
<a href="https://ru.wikipedia.org/wiki/%D0%A1%D0%B0%D0%BC%D0%BE%D0%B8%D0%BD%D0%B4%D1%83%D0%BA%D1%86%D0%B8%D1%8F">Так же есть ЭДС самоиндукции</a>, появляющаяся при изменении тока, проходящего по обмоткам. <br />
E = - L* (dI/dt) <br />
- как видно тут участвует производная тока и самоиндукция будет влиять на работу мотора только когда ток меняется, КЭП.<br />
<br />
e - величина линейная, зависит от угловой скорости ротора, равна k_e * w. k_e - константа обратной ЭДС.<br />
<br />
Пользуясь вторым правилом Кирхгофа можно записать уравнение напряжения в моторе:<br />
<br />
Vs = R*I + L*(dI/dt) + e;<br />
<br />
тут Vs - напряжение питания мотора.<br />
<br />
Не сложно переписать уравнение так, что бы выразить производную тока:<br />
<br />
<b>dI/dt = (Vs - (R*I) - e) / L;</b><br />
<br />
Уже хорошо, но кроме тока нам интересны ещё и обороты движка, и крутящий момент же.<br />
Для начала можно описать, так сказать, уравнение равновесия крутящих моментов:<br />
<br />
Me = Mm + Mf + Ml<br />
<br />
Me = электрический крутящий момент, т.е. момент, сгенеренный обмотками ротора.<br />
<div style="text-align: left;">
Mm - механический момент ротора, J* (dw/dt) где J - момент инерции ротора, кг*м^2</div>
Mf - момент трения ротора, линейно зависит от угловой скорости, k_f * w,<br />
Ml - момент внешней нагрузки на ротор.<br />
<br />
w - угловая скорость ротора [рад/с]<br />
<br />
т.е. Me = J*(dw/dt) + k_f*w + Ml;<br />
<br />
Тут есть важная штука: "электрический" момент линейно зависит от тока на обмотках якоря и его коэффициент является одной из важнейших характеристик моторов. То есть "электрический" момент (Me) = k_t * I;<br />
<br />
k_t * I = J*(dw/dt) + k_f*w + Ml;<br />
<br />
Выразим производную угловой скорости ротора:<br />
<br />
<b>dw/dt = (k_t*I - k_f*w - Ml) / J</b><br />
<b><br /></b>Теперь у нас есть 2 дифференциальных уравнения, которые можно проинтегрировать и получить графики работы движка.<br />
<br />
Для проверки себя я заскринил реальный график реального движка, подложил в юнити в виде плоскости с текстурой под свой рисуемый график.<br />
<br />
Изначально ничего не сошлось, т.к. я не корректно вбил коэффициенты. Плюс к тому не ясно для какого точно напряжения построен график и какое точно сопротивление было у движка, для которого он строился. Коэффициенты то есть в даташите, но они немного отличаются от того, что на графике!<br />
<br />
Что бы график сошёлся идеально, необходимо было крутить несколько коэффициентов. Это достаточно геморно и потому я использовал алгоритм оптимизации Левенберга-Марквардта для автоматической подстройки параметров ))) Критериями ошибок стали максимумы и производные графиков тока и оборотов мотора, а так же разница между идеальными и реальными экстремумами графиков мощности и эффективности, вот что получилось:<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-nep85ZSu2BQ/Vo6B-bdRkjI/AAAAAAAAAYI/Gav0Y3FnFC0/s1600/plot_dc_motor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="346" src="http://3.bp.blogspot.com/-nep85ZSu2BQ/Vo6B-bdRkjI/AAAAAAAAAYI/Gav0Y3FnFC0/s640/plot_dc_motor.png" width="640" /></a></div>
<span style="font-family: Verdana, Helvetica, sans-serif;"><span style="background-color: #e2f0f8; font-size: 13.3333px; line-height: 18.6667px;"><br /></span></span>
<br />
Тут gizmo используется для отрисовки графиков, под ними подложка с текстурой реальных графиков. Всё вполне совпадает )<br />
<br />
А вот график по времени. Сначала включается питание мотора и потом по достижению максимальных оборотов питание отключается. Видны 2 всплеска на графиках - большой пусковой ток и выброс в отрицательную сторону при выключении. Синий график - обороты, красный - ток.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-DSe-RQsIEFc/Vo6ILqV6-NI/AAAAAAAAAYY/M-8574AG1vM/s1600/Plots.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="400" src="http://1.bp.blogspot.com/-DSe-RQsIEFc/Vo6ILqV6-NI/AAAAAAAAAYY/M-8574AG1vM/s400/Plots.png" width="318" /></a></div>
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-53151507831650039612015-11-08T12:51:00.001+03:002015-11-08T15:28:45.030+03:00Коптер<div dir="ltr" style="text-align: left;" trbidi="on">
Начал совсем недавно пилить свой квадрокоптер. За основу пока взят мой борд STM32VLDISCOVERY. У него на борту не очень крутой контроллер STM32F100RBT6: 24MHz, 128Kb FLASH, 8Kb RAM, однако пока что его даже много ) <br />
<br />
Что успел запилить:<br />
Напаял железки на борд! 2 RFM70 радио модуля пока на 1 общий SPI, акселерометр <a href="https://www.bosch-sensortec.com/de/homepage/products_3/3_axis_sensors/acceleration_sensors/bma280/bma280">BMA280</a> на отдельный SPI, собрал узел контроля оборотов коллекторного мотора, схемка вышла не сложная ) Через полевой транзистор IRLML2803 <a href="https://ru.wikipedia.org/wiki/%D0%A8%D0%B8%D1%80%D0%BE%D1%82%D0%BD%D0%BE-%D0%B8%D0%BC%D0%BF%D1%83%D0%BB%D1%8C%D1%81%D0%BD%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D1%83%D0%BB%D1%8F%D1%86%D0%B8%D1%8F">ШИМ</a>-ом включаю/отключаю питание у мотора, скважностью пульса регулируются обороты, так же добавлен диод Шоттки в качестве шунта мотора, резистор на 100К что бы не происходило произвольного открывания затвора транзистора если WPM пин в подвешенном состоянии.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-ZxUTAHHghew/Vj8_9jRVvhI/AAAAAAAAAXo/01cboRL4rBY/s1600/motor_connection_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="160" src="http://2.bp.blogspot.com/-ZxUTAHHghew/Vj8_9jRVvhI/AAAAAAAAAXo/01cboRL4rBY/s400/motor_connection_2.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
И для удобства запилил простенький командный интерфейс через виртуальный COM порт, могу теперь устанавливать "обороты" движка через консоль.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Так же завёл акселерометр, что, в общем то, не сложно, используя стандартную библиотеку от BOSCH <a href="https://github.com/BoschSensortec/BMA2x2_driver">https://github.com/BoschSensortec/BMA2x2_driver</a>. Хотя конечно некоторые вещи в нём не очевидны! Например, у него в <span style="font-family: "courier new" , "courier" , monospace;">bma2x2.c</span> файле в глобальной переменной <span style="font-family: "courier new" , "courier" , monospace;">u8 V_BMA2x2RESOLUTION_U8 = BMA2x2_14_RESOLUTION;</span> захардкодена битность показаний осей акселерометра, всегда 14 бит. И это странно тем, что мне нужно менять чужой драйвер что бы получить другую битность.</div>
<div class="separator" style="clear: both; text-align: left;">
А ещё одна корявость состоит в том, что у них же в файле-примере<span style="font-family: "courier new" , "courier" , monospace;"> bma2x2_support.c</span> есть семплы имплементации функций чтения/записи SPI и чтение осей акселерометра. Акселерометр позволяет последовательно читать несколько регистров за раз! И для этого в семпле используются буферы и их размер задефайнен как <span style="font-family: "courier new" , "courier" , monospace;">#define SPI_BUFFER_LEN 5</span> чего не хватает для работы с функцией <span style="font-family: "courier new" , "courier" , monospace;">bma2x2_read_accel_xy</span>z которая в этом же семпле и используется. Я изначально внимание не обратил и долго думал, почему у лежащего горизонтально акселерометра ускорение 0 ) Оказалось ось Z просто не вмещалась в буфер!</div>
<br />
Радио пока через RFM70. Для реального применения в квадрокоптере этот радио модуль не подходит из за малого радиуса действия (метров 10), но хоть что-то. Будет использоваться для передачи команд с пульта на коптер.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-HUOcioCQekU/Vj8clIbmvRI/AAAAAAAAAXY/B711uwtICwE/s1600/WP_20151108_01_54_16_Pro.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="360" src="http://4.bp.blogspot.com/-HUOcioCQekU/Vj8clIbmvRI/AAAAAAAAAXY/B711uwtICwE/s640/WP_20151108_01_54_16_Pro.jpg" width="640" /></a></div>
<br />
<br />
<br />
<br />
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-75339239015880138122015-11-04T15:57:00.002+03:002015-11-04T15:57:52.276+03:00Мелкий апдейт движка<div dir="ltr" style="text-align: left;" trbidi="on">
Добавил систему ввода, поддерживаются множество клавиатур, мышей, джойстиков, всё крайне просто и достаточно удобно.<br /><br />
<span style="font-family: Courier New, Courier, monospace;">auto keyboards = Input::instance()->keyboards();</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>if(keyboards[0]->get_key_state(0x57)){</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>gameObject->transform->set_local_position(gameObject->transform->get_local_position() + gameObject->transform->forward() * (deltaTime * move_speed));</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
Так же начал прикручивать AMP рендереры, пока что для параметрических поверхностей, чуть позже сделаю биндинги к полигональным моделям. Таким образом можно будет делать гибридный рендер стандартный (растеризацией полигонов) и Path Tracing-ом.<br /><br />Сложнейший рендер: сферка отрендеренная трассировщиком пути, в цвете выведены нормали.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://2.bp.blogspot.com/-oVfYeGPw4Vw/VjoAt1xrppI/AAAAAAAAAW8/pOsktiusidg/s1600/iray.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="376" src="http://2.bp.blogspot.com/-oVfYeGPw4Vw/VjoAt1xrppI/AAAAAAAAAW8/pOsktiusidg/s640/iray.png" width="640" /></a></div>
<br />
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-3766377197978582502015-05-25T11:42:00.000+03:002015-05-25T11:43:12.689+03:00Unity Killer :D<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-drsgzLhHknc/VWLgXYpbRaI/AAAAAAAAAWc/wd4Dfx-uV10/s1600/pasted_image_at_2015_05_24_11_41_pm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-drsgzLhHknc/VWLgXYpbRaI/AAAAAAAAAWc/wd4Dfx-uV10/s1600/pasted_image_at_2015_05_24_11_41_pm.png" /></a></div>
Пописываю параллельно с остальными проектами "убийцу Unity" :D <br />
<br />
Что уже есть:<br />
Компонентная система сущностей, иерархии трансформов, шейдеры, система материалов удобная, класс для рисования Gizmo, меши с сабмешами, рендеринг из нескольких камер в кадре и так ещё всякие мелочи) Скоро добавлю загрузку текстур и мешей.<br />
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-19140109279652994302015-04-05T19:14:00.001+03:002015-04-11T10:52:24.522+03:00Атмосфера<div dir="ltr" style="text-align: left;" trbidi="on">
Запилил по-быстренькому атмосферу для планеты в Unity<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-7FsJi34x-vE/VSjSVgbygZI/AAAAAAAAAWA/NByje5UHGF0/s1600/earth4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-7FsJi34x-vE/VSjSVgbygZI/AAAAAAAAAWA/NByje5UHGF0/s1600/earth4.png" height="532" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-gZO34lzFCsI/VSjSVlBNAkI/AAAAAAAAAV8/PUvqwo9xH-A/s1600/earth5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-gZO34lzFCsI/VSjSVlBNAkI/AAAAAAAAAV8/PUvqwo9xH-A/s1600/earth5.png" height="514" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://4.bp.blogspot.com/-WyeRye_6CbE/VSF4OnZQcWI/AAAAAAAAAVo/9AY_P4E8WmM/s1600/earth3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-WyeRye_6CbE/VSF4OnZQcWI/AAAAAAAAAVo/9AY_P4E8WmM/s1600/earth3.png" height="422" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-47056784782357875112015-03-08T00:02:00.003+03:002015-03-08T00:02:39.399+03:00Микро апдейт<div dir="ltr" style="text-align: left;" trbidi="on">
Немного обновил осциллограф - добавил деления на осях и границах экрана для удобства визуального определения значения функции, изменил цвета, сделал вывод снизу экрана осциллографа инфу о каналах - ID, скейл по Y (значение на ячейку), цвет канала. Теперь легче ориентироваться. Ну и кламп графиков по окну осциллографа добавил )<br /><br />В коде стабилизации квадрика поправил несколько ошибок, сменил PID контроллер Yaw оси на PD т.к. интеграл ошибки считать по этой оси нельзя, знак ошибки постоянно меняется, стало всё стабильно работать без внезапных улетаний в космос )<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-VrfhreAxq40/VPtnYn0B8oI/AAAAAAAAAU8/kW-S-Cw3RMU/s1600/osc1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-VrfhreAxq40/VPtnYn0B8oI/AAAAAAAAAU8/kW-S-Cw3RMU/s1600/osc1.png" height="514" width="640" /></a></div>
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-86642687979704358502015-02-15T23:08:00.001+03:002015-02-15T23:08:38.843+03:00Заработала стабилизация<div dir="ltr" style="text-align: left;" trbidi="on">
Подкрутил стабилизацию, теперь осталось добавить контроль Yaw вращения и в первой итерации контроллер полёта готов. Умеет сам держать заданную высоту, умеет слушаться команд "пульта" ( в реале - джойстика) и собсно держать нужную заданную ориентацию. Всё считается по-честному.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-3MR6fJFfs2U/VOD8umezXHI/AAAAAAAAAUc/L50IXa05a6o/s1600/quad_upd0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-3MR6fJFfs2U/VOD8umezXHI/AAAAAAAAAUc/L50IXa05a6o/s1600/quad_upd0.png" height="434" width="640" /></a></div>
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-78208811675657245892015-02-15T00:37:00.002+03:002015-02-15T00:39:53.917+03:00Апдейт виртуального мультикоптера<div dir="ltr" style="text-align: left;" trbidi="on">
Перепиливаю систему стабилизации мультикоптера. Переписал код работающий с ориентацией коптера с углов Эйлера на кватернионы, всё стало клёвее, ошибка считается в локальном пространстве коптера, представляет собой вектор "наклона" коптера относительно заданной ориентации. Dot-ом для каждого считаю развешивание ошибки между движками (на рисунке - жёлтые линии выходящие из движков), получается прям очень удобная система! Она не зависит от количества и расположения движков, всё автоматом развешивается и работает. Осталось накинуть обратно PID контроллеры и квадрик снова будет летать )<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://1.bp.blogspot.com/-qQj6-8a5bTI/VN_APnilWWI/AAAAAAAAAUQ/7TAuNXdz8BE/s1600/quad_quat.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://1.bp.blogspot.com/-qQj6-8a5bTI/VN_APnilWWI/AAAAAAAAAUQ/7TAuNXdz8BE/s1600/quad_quat.jpg" height="420" width="640" /></a></div>
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0tag:blogger.com,1999:blog-824665217355978368.post-40555456615405417392015-02-14T19:27:00.002+03:002015-02-14T19:28:25.743+03:00Квадрокоптер<div dir="ltr" style="text-align: left;" trbidi="on">
Пришёл наконец с Китая Hubsan X4 H107L квадрокоптер. Самый простой в серии X4, но летает весьма круто. Правда, из коробки он по ходу вообще не был откалиброван, летел в сторону, стики странные значения по разным осям выдавали, но после стандартных калибровок стиков/акселерометра всё пришло в норму )<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://3.bp.blogspot.com/-4okbWq7akvs/VN93YKZRDgI/AAAAAAAAAT8/5UuRfJjuTxE/s1600/WP_20150214_19_19_05_Raw.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://3.bp.blogspot.com/-4okbWq7akvs/VN93YKZRDgI/AAAAAAAAAT8/5UuRfJjuTxE/s1600/WP_20150214_19_19_05_Raw.jpg" height="478" width="640" /></a></div>
<br /></div>
L-progerhttp://www.blogger.com/profile/16599175092049339608noreply@blogger.com0