Jump to content

    

amaora

Участник
  • Content Count

    575
  • Joined

  • Last visited

Community Reputation

0 Обычный

1 Follower

About amaora

  • Rank
    Знающий

Recent Profile Visitors

5318 profile views
  1. В стационарном режиме вращения заполняю таблицу из 6-ти состояний холлов. В каждом столбце количество попаданий в это состояние и сумма векторов положения. После беру среднее от этой суммы и получается среднее положение для каждого состояния холлов, оно и используется при интерполяции. Ну и отбраковка по количеству попаданий и величине ожидаемой суммы. Если одно из состояний ни разу не зафиксировано то ошибка, если одно состояние фиксируется в сильно разных положениях то ошибка. Можно придумать еще условий. Эталонное положение от бездатчикового наблюдателя. По длине периода этих отклонений? Не надежно, но можно подумать.
  2. Слишком большое искажение фазного тока, в чем то другом дело. У меня есть калибровка датчиков Холла, но это больше для упрощения подключения и диагностики, провода чтобы можно было перепутать. Интерполяция все равно будет работать неидеально когда скорость начнет менятся.
  3. Что значит получается, какой зададите такой и будет ток по оси D. Это вопрос следующего контура управления. Ну и причины задавать D ток могут быть разными, не только использование реактивного (reluctance) момента или ослабление, может быть инжекция сигнала для бездатчикового метода, первоначальный разгон без обратной связи по положению и т.д. Про напряжение наверно стоило уточнить, что напряжением надо считать среднее значение за один период модуляции. На этом уровне нет смысла рассматривать физические пространственные магнитные поля, они зависят от конструкции двигателя. Управление работает с абстрактной двухфазной синхронной машиной, которая достаточно точно описывает поведение реального двигателя, в той части которая требуется для управления. Здесь все величины символические.
  4. Смысл векторного управления лишь в регулировании вектора тока в подвижной DQ системе координат связанной с ротором. Вектор напряжения формируется регулятором и затем преобразуется в неподвижную систему координат. Какой задавать вектор тока зависит от желаемого управления. То есть задаёте вектор тока, а напряжение будет такое, которое сделает регулятор. Вектор тока задаёте исходя из выражения для момента, ограничений и необходимости ослабления поля ротора. Но с этого места становится уже не очень просто учитывать все требования. Если ротор без выраженной полюсности и DQ индуктивности не сильно отличаются, то весь момент создаёт Q ток. Если при этом вам не нужно ослабление и нет ограничений, то структура получается простой как на вашем рисунке.
  5. Клавиши назначены не на все действия. Посмотреть действия можно вызвав контекстное меню на каком-нибудь элементе, они подсвечиваются при наведении. Можно на заголовке сверху, на каждой оси, на легенде фигур. В каждом меню слева подписано если есть клавиша для этого действия. По большому списку меню есть нечёткий поиск (при открытом меню начинаем набирать текст, в меню останутся только совпадения), для тех у кого ~100+ графиков или файлов.
  6. Есть README.md и пример конфигурационного файла с описанием всех настроек. Так же можно запустить GP с единственным параметром именем файла и порта. Или можно выбрать файл нажав "O". Настройки порта программа не умеет, всегда работал с уже настроенным портом. Пример CSV файла, заголовок с названиями параметров, единиц измерений и числовые данные. Такой файл можно открыть без настроек, и выбрать столбцы/оси/цвета уже в программе. Или вот пример моей конфигурации для real-time построения. #!/home/amaora/util/gp # vi: ft=conf chunk 20 load 0 1200 text "/dev/rfcomm0" mkpages -1 group 0 -1 deflabel 0 "Time (s)" defscale 0 0.05 0
  7. У всех разные требования, готовое не подходит и пишут свое. У меня нет текстовых меток и отправки параметров обратно, и не думаю в эту сторону. https://sourceforge.net/projects/graph-plotter/
  8. Меня больше всего удивило когда я однажды изобразил умножение на 10 с помощью сдвигов и сложений, а gcc заменил это на одну инструкцию mul, или даже деление там было. По переупорядочиванию, думаю компилятор все правильно делает. Его задача обеспечить меньший расход тактов на выполнение всей функции, он этого добивается переупорядочиванием независимых инструкций для оптимизации загрузки конвейера. Вам же хочется оптимизировать на скорость (или скорее на чистоту асм-листинга?) выполнения отдельный кусочек этой функции. Если такие детали важны то действительно надо написать этот код вручную а не выжимать из компилятора. Проверьте только, может быть помещение той инструкции между вашими ничего не стоит по времени.
  9. Я не очень требователен к функциям отладчика, и без него обхожусь, но вот этим пользуюсь иногда. https://github.com/blacksphere/blackmagic/wiki
  10. Здесь много чего мешает: - Для области адресов внутренней флешь действует write-through, то есть данные на запись не лежат в кэше а сразу отправляются на запись. Ну допустим на другом cortex-** будет write-back кэш (или через MPU наверно это можно организовать, не знаю не проверял). - Запись во флешь не делается случайно, выше приводил код записи, и там уже сделан сброс кэша непосредственно после записи каждого слова, принудительный write-through. - Запись не пройдёт без команды через периферийные регистры флеша, так если из кэша вдруг сбросятся данные когда мы собрались стирать (или уже стерли) страницу, то наверно будет MemoryFault.
  11. Не понимаю зачем, после делаю инвалидацию для того чтобы последующие операции чтения не взяли мусор из кэша, а до стирания для чего?
  12. Есть несколько мест в коде на счёт которых я сомневаюсь в их корректности для m7 в частности и для всех других cortex-**. Хотел бы спросить чужого мнения об этом. (1) Это реализация критической секции. Вызываться может из контекста потоков rtos и из обработчиков прерываний. Безопасно ли так читать BASEPRI? Нужны ли ISB/DSB и в каком порядке? Наоборот? Нужно ли обкладываться запретом прерываний как говорит 837070 erratum? int hal_lock_irq() { int irq; irq = __get_BASEPRI(); __set_BASEPRI(1 << (8 - __NVIC_PRIO_BITS)); __ISB(); __DSB(); return irq; } void hal_unlock_irq(int irq) { __set_BASEPRI(irq); } (2) По поводу 837070 erratum, во freertos в сохранялке контекста сделали вот так: $ diff -u ARM_CM4F/port.c ARM_CM7/r0p1/port.c ... @@ -449,9 +437,11 @@ " \n" " stmdb sp!, {r0, r3} \n" " mov r0, %0 \n" + " cpsid i \n" /* Errata workaround. */ " msr basepri, r0 \n" " dsb \n" " isb \n" + " cpsie i \n" /* Errata workaround. */ " bl vTaskSwitchContext \n" " mov r0, #0 \n" " msr basepri, r0 \n" Нужно ли это? Почему не достаточно dsb/isb если в описании erratum речь шла только про то, что под угрозой лишь одна инструкция после msr? В других местах freertos где делается запись в BASEPRI ничего не добавили. (3) При записи данных во флешь делаю сброс и аннулирование кэша по этому адресу, уходит вся строка кэша как я понимаю. Но так же известно, что для области флеша используется write-through и может быть ничего и не нужно специально предпринимать (если предположить, что перечитывать флешь не хотим)? А может быть ещё и ISB не хватает перед обращением к DCCIMVAC? while (long_flash < long_end) { /* Program flash memory. * */ *long_flash = *long_s++; __DSB(); #ifdef _HW_STM32F722 /* D-Cache Clean and Invalidate. * */ SCB->DCCIMVAC = (u32_t) long_flash; __DSB(); __ISB(); #endif /* _HW_STM32F722 */ long_flash++; ... (4) После стирания страницы флеша очевидно необходимо аннулировать эту область в кэше, здесь вопроса нет, код не привожу. Спасибо.
  13. Раньше так и делал, выше приводил тест такого метода на octave. Ошибка агрегации хорошо компенсируется. Но это все же квадраты от исходных данных, и деградация точности тоже по квадрату от числа обусловленности. Смысл в этом методе только как в наиболее вычислительно простом, если делать LDL разложение, то можно и без квадратных корней обойтись. Про регуляризацию с параметром не понял как это надо использовать. Предлагаете под каждую задачу анализ проводить? Так и приедем к тому чтобы SVD делать. А я анализирую число обусловленности только X матрицы а не [X Z], так даже непонятен смысл, у меня всегда огромные числа cond([X Z]).
  14. Сделать какие-то оценки чтобы понять, что получился мусор а не решение было бы полезно, но пока обойдусь. Априорно предполагаю хорошую обусловленность системы, это обеспечивается в большинстве случаев, т.к. я сам задаю "зондирующий сигнал X". Ошибка копится при агрегировании большого количества данных в одну матрицу, а делать это в двойной точности слишком дорого. Достаточно хороший результата получен с помощью ортогональных преобразований и каскадирования. https://sourceforge.net/p/liblse/code/ci/default/tree/README.md
  15. Здесь важно с какими параметрами делали configure, в make не надо ничего передавать. Сначала наверно надо binutils установить, собрать временный gcc, им собрать glibc (или другую libc), а после уже собирать финальную версию gcc. Давно вручную не собирал, не помню точно. Можно попробовать вот здесь почитать, или спросить у автора темы.