Мои размышления про экранную клавиатуру для Flipper Zero под экранчик 128х64 пикселя

v3ko53wbxu5vwb6oailabrf_ucy.gif


Недавно я увидел пост с приглашением разработчиков в проект Flipper Zero и подал заявку. Меня добавили в репозиторий с прошивкой и я стал много думать над юзабилити устройства. Приснилось, что мне надо отсканировать кучу ключей-брелков от разных подъездов. Во сне были разные люди, квартиры, дождь, и почему-то мне дали целую горсть этих желтых кругляшей, отличающихся друг от друга только количеством грязи на них. И естественно, чтобы как-то совладать с этим беспорядком, я решил внести все эти ключи во Flipper Zero.
Прямо во сне, я заносил новые идентификаторы и все они добавлялись в менюшку как «Ключ», что делало действо еще бессмысленней. Получился большой список, состоящий только из слова «Ключ». Подумалось, что надо переписать прошивку. И тут как раз преимущество сна — все задуманное сбывается одномоментно. Ключи стали добавляться с рандомным суффиксом как «Ключ 74», а следом за ним мог добавиться «Ключ 22». Номер именно рандомный, не путать с контрольными суммами или хешами. В принципе, если есть хорошая память, то можно запомнить, что «Ключ 22» от Ленина 54, а «Ключ 74» от Пушкина 29. Подумалось, что неплохо бы как-то редактировать номера, прямо на Флиппере, прямо в списке ключей: у нас же свободны кнопки влево-вправо, пусть они инкрементируют/декрементируют номер! А длинное удержание вызовет вызов полноценной клавиатуры! Но стоп, какую клавиатуру рисовать? Стандартную Qwerty с переключением на Йцукен? Русифицированную Яверты? У нас же экран всего 128×64 пикселя, к тому же в него надо как-то запихнуть еще вывод набираемого! Как все это уместить? Неужели вводить текст Азбукой Морзе?

Примитивная клавиатура


zxch2-puf92vjdxtpw0ebyeqs38.gif
Сказать, что набирать что-либо на такой клавиатуре удобно — явно нельзя. Что быстро — тоже. Простота и большой набор символов — это единственное, что тут можно получить, а в остальном же от такой клавиатуры хочется бежать и не оглядываться. Удивительно, но в прошлом подобный метод ввода был весьма распространен.

Qwerty


Так, а что, если взять стандартную клавиатурку от Андроида, применить эффект линзы и посмотреть, что из этого выйдет? 10 часов в Афтер Эффектсе и вот оно:
zal3w2ly6jgm1j0utmn94bukfxe.gif

У меня был скрипт, который конвертирует графику в CGA-палитру, после обработки получилось такое:
lhun7bsn2vr1mrz8u4bxngg5gqs.gif

Мне это понравилось, и даже понравились полутона. СТОП. На Флиппере же чернобелый экран! Но зато он обладает энерционностью, а значит можно получить полутона, быстро включая/выключая пиксели. Пришлось изобретать свой вариант дизеринга. В процессе был изобретен Дизеринг Курильщика:
f6brp7be4gxy7l6q6mnsaqaqrdy.png

Это вариация дизеринга Баера и немного модифицированной матрицы распределения ошибок Билла Аткинсона. После некоторой отладки и исправления 9000 ошибок, получилось такое:
wqw-_ziopkyy8vocrynlion4t3o.gif

Не сказать, что этот вариант мне нравится сильно больше, зато на LCD-экранчике оно должно выглядеть лучше, особенно хорошо должны получиться полутона за счет постоянного вращения матриц. Пока что я не получил свой Флиппер, так что проверить на деле это не могу, но в теории должно выглядеть хорошо.

Хм, а если постараться и нарисовать как можно более маленькую клавиатурку?
38mgaftwtpc8hxx8mfgfcccnd0g.gif

В принципе, получилось неплохо. Все вмещается, если захотеть. Опционально можно припилить клавишу RUSLAT, как и много других полезных клавиш. Но каких? Залезть в стандарт HID и натырить оттуда клавиши «кофе» и «красная кнопка»?

Раскладка


Стандартная раскладка QWERTY имеет следующие особенности:

  1. Предназначена для печатающих машинок, подразумевающие ручной ввод (двух рук)
  2. Предполагается смена рук при наборе текста. Пока одна рука нажимает клавишу, вторая рука готовится к нажатию. Однако, многие слова английского языка могут быть набраны только на левой части клавиатуры.
  3. Диагональное расположение клавиш ведет свою историю от физического расположения рычагов на печатающей машинке

Следующие слова приписываются Августу Двораку:

Можно, не прилагая особых усилий, создать десятки клавиатурных раскладок, которые будут по крайней мере не хуже, чем универсальная клавиатура Шоулза. Если буквы и символы из трёх нижних рядов клавиатуры Шоулза перемешать и расставить случайным образом, то чаще всего получится более удобная клавиатурная раскладка, при которой нагрузка на руки и отдельные пальцы будет распределена более равномерно. При этом станет меньше слов, набираемых лишь одной рукой, и будет меньше сложноосуществимых последовательностей нажатий буквенных клавиш, чем при работе на упомянутой выше универсальной клавиатуре Шоулза.

Но так получилось, что ни Дворак, ни его приемник, Колемак, так и не завоевали популярности.
Но вернемся к Флипперу. У нас есть на нем рычаги? Можно ли использовать сразу 2 руки для набора текста? Имеет ли смысл чередовать руки? Хотим ли мы более эффективно задействовать мизинцы, как это рекламирует автор Колемак? Нужна ли нам совместимость с популярными Windows-хоткеями, такими как CTRL+C/CTRL+V? Ответ на все эти вопросы: НЕТ.

Шарики

Я взял пару статей из википедии, скопировал из них текст и посчитал уникальные символы, вот они:

!$%&'(),-./01234567
89:;?ABCDEFGHIJKLM
NOPQRSTUVWXYZ[]a
bcdefghijklmnopqrstu
vwxyz|£¥«°²»àéœ́АБВ
ГДЕЖЗИЙКЛМНОПРС
ТУФХЦЧШЭЮЯабвгде
жзийклмнопрстуфхцч
шщъыьэюяё—’""…№
↑▲

Забавно, но тут нету символа двойной кавычки », зато есть «ёлочки».

Я попробовал визуализировать частоту использования каждой буквы, но сразу пришлось применить логарифмическую шкалу, чтобы хоть что-то разглядеть:

gy1lbbfztbiwdne8koznqwdzdzw.png

Давайте подумаем, как расположить эти символы на экране, чтобы пользователю было удобнее их вводить?

Самая первая идея: посчитать частоту использования той или иной буквы вместе с соседями. И использовав эти данные, запустить симулятор «Шариков», где между шариками есть некоторая сила притяжения, равная частоте использования этих букв по соседству.

Первый опыт был таким:
06qybpsdwygiggn4_6_ryh3tjmq.gif

Тут мало что можно разглядеть, но если приглядеться, то можно увидеть, как кириллица и латиница образовали между собой кластеры, практически не связанные между собой, а из пробела вылетают малоиспользуемые символы.

После 9000 часов отладки и боли, была сделана более приятная глазу симуляция:

06qybpsdwygiggn4_6_ryh3tjmq.gif

К моему разочарованию, символы сильно мешают друг другу двигаться. Я попробовал поиграться с силой притяжения, менял ее динамически, даже устраивал ручные «вихри», но ничего не помогало.

i1tdcspycmh_enwvxp1cusdg71o.png

Тут уже видно, что хотя кластеры уже по большей части сформированы, но в них присутствуют инородные элементы. Надо придумать какой-то другой способ расстановки клавиш…

С другой стороны, если положить это все в диаграмму Вороного…

m_z9aiz75tn17o0luhktybtvple.png
Выглядит очень круто! Хм, да с такой клавиатуркой можно будет даже оставить Флиппера и начать производство собственных реальных клавиатур! Правда, кому еще нужны клавиатуры для 1-пальцевого ввода? Что мне писать на кикстартере? Пойду плакать в подушку над очередным своим бесполезным изобретением.

Генетика

Ладно, поплакав, я продолжил свои изыскания. За основу я взял прототип китайской клавиатурки:
uqqck02ev5kxv-m7lsnjpxv67xa.jpeg

А именно, я взял матрицу 16×16 знакомест и насыпал туда набор символов в случайном порядке. Вообще, по началу я хотел их как-то красиво упаковать, использовав частотные данные о соседних символах, в голове проносились аналоги деревьев Хаффмана, но ничего толкового я родить так и не смог. Потому просто расположил клавиши в центре, располагая их по спирали от центральной ячейки. В последствии, я еще начал их перемешивать, так что мытарства с деревьями Хаффмана были излишни.

А дальше я просто запустил простой генетический поиск: делал набор для мутаций, отбирал лучшие, делал их родителями следующих поколений. И так пока не зависнет, т.е. не упрется в эволюционную яму.

Было много экспериментов:

  • Сначала я переставлял 2 соседние клавиши местами, а в конце выяснил, что лучше передвигать клавишу по всему полю
  • Количество мутаций в одном поколении варьировал от 30 до 3000. Выяснил, что пусть лучше рожает чаще и чаще дохнет, для эволюции это полезней — остановился на 30.
  • Мутировать за раз лучше как можно меньше, таким образом оно сможет более точно подстраиваться на последних этапах, когда все будет почти закончено.
  • Эволюционная яма наступает не сразу, а где-то за 5к итераций до того, как станет очевидной
  • Если уперлись в яму и долго не можем найти новых улучшений, то лучше все бросить и начать с нуля, может быть в этот раз эволюция пойдет лучшим путем. Из-за этого в результатах есть досадные недостатки в виде пары клавиш, которые присутствуют не в своих кластерах

Далее я считал, насколько эффективной оказалась та или иная мутация. Для этого я взял текст из Википедии, и сделал что-то вроде симулятора процесса набора текста. Виртуальная клавиатура 16×16, виртуальный джойстик, виртуальный текст. В конце симуляции я смотрел, сколько понадобилось нажатий, чтобы набрать этот текст. Это и был рейтинг эффективности. Если количество нажатий было меньше, чем в других вариациях мутации, и тем более до переставления клавиш, то значит эта «мутация» оказывалась лучше и она использовалась для продолжения обсчета. Получилось в итоге такое:

_yawj8ubnx-tyygd2f93zcrhxd4.png

yg070hsbbuactgufjiqofmkcaw0.png

bqjluk13diliem_mcbpq2teaqp4.png

votsnkobyuz25fkaonyqrq9hnpe.png

aoyhp-h6gcdtrzu1pvyoh84jvra.png

Местами мне очень нравится получившийся numpad, местами кириллица и латиница образовали некоторое подобие «Инь и Янь», почти везде символы доллара, евро и фунтов находятся рядом, как и символ процента. Номер слева означает, сколько раз надо будет нажать на кнопки джойстика, чтобы набрать тестовый текст. Возможно, если бы я запустил симулятор на недельку, то были бы более интересные варианты, но у меня старенький компьютер для таких экспериментов. А внимательный читатель найдет еще и полупасхалку-полубагу: почти на всех вариантах раскладки присутствует слово KFC, так как обучалось оно на статье про KFC и каких-то теннисисток.
В принципе, меня подмывает взять и переставить некоторые клавиши руками, особенно кириллическую Й, которая вечно оказывается около латиницы, или же латинскую Х, которая порой бывает среди кириллицы, а символы равномерно распределить кругом или ссыпать в кучку, но… А что ответит эволюция на это? Насколько эффективным будет такая перестановка? Да, писать интерактивную переставлялку мне было лень. Но оно и к лучшему: теперь я знаю, что даже для кириллицы/латиницы может быть несколько раскладок, а пользователь уж пускай сам выбирает, что ему лучше.

Если интересны другие варианты раскладок, которые сгенерировались за время обсчета, то посмотрите файлы layouts.html и layouts-more.html

Можно экспериментировать достаточно долго, вот идеи для опытов:

  1. Заворачивание краев пространства друг на друга. Т.е. это не курсор двигается по клавиатуре, а клавиатура двигается, причем по мере ухода в одну сторону экрана, она появляется с другой стороны.
  2. Отказ от двумерного пространства и заворачивание плоскости в какой-то трехмерный объект, скажем натягивание на глобус или же еще какую геометрическую фигуру. Возможностей зацикливания пространства становится больше.
  3. Добавление частоиспользуемых символов в нескольких экземляров. К примеру, почему бы не сделать десяток пробелов? Вот в Колемаке есть 2 бекспейса, только в нашем случае умножать стоит скорее пробел.
  4. Добавление частоиспользуемых буквосочетаний, на манер дерева Хаффмана, где длинные последовательности заменяются короткими. В нашем случае — частые последовательности букв заменяются одинарными нажатиями
  5. Динамическое подставление символов, предугадывая дальнеший набор текста, как это сделано в Dasher

Если кто не знает про Dasher, то бегом сюда: f-droid.org/en/packages/dasher.android — тут все про наш девайс и даже более: ввод текста с джойстиков, трекболов, мышек, глазных трекеров и прочих одноручных, однопальцевых и носимых устройств. Интерфейс может быть запущен хоть в разрешении 32×32 пикселя, и это без потерь для юзабилити. Работало на Pocket PC и пережило долгие годы! Но, как бы я не фанател от этой штуки, не смотря на большой выбор опций, я так и не научился этим пользоваться, ощущая при этом удобство, поэтому для меня это скорее технодемка возможностей, возможности взаимодействия с машиной. Если кто-то хочет портировать Dasher, то милости просим, патчи до сих пор приходят в репозиторий регулярно, думаю будет много желающих, увидеть такую штуку на своем Флиппере.

Сюда же можно занести разнообразные варианты аккордовых клавиатур, или же экранных клавиатур времен Palm, таких как MessagEase. Идея, лежащая в MessagEase замечательная, но проблема в том, что зажатие 2-х кнопок лично для меня неприемлемо, потому лично я превращать Флиппера в аккордовую клавиатуру не буду. Но я уверен, что настоящий хакерский девайс не сможет выжить без аккордовой клавиатуры, потому ее наверняка добавит кто-то еще.

Подводя итог: вариантов клавиатуры может быть великое множество. Но я должен не только представлять, как это должно быть, но еще и реализовать все описанное выше. Так что, если есть желающие — можете попробовать, а мне работать надо.

Реализация

А в следующей части мы попробуем реализовать все задуманное. Мы напишем небольшой эмулятор и попробуем изобрести API.

На последок, вот вам еще несколько анимаций с концептами клавиатурки:
nnhnknmdkgfevupnhru6ve8zxtu.gif

Клавиатурка, натянутая на то, что в Максе зовется Torus Knot:

_6bnfvwxmd_xjk-x0r1emfu-aw4.gif

А это, попытка натянуть сову на глобус^W^W^Wклавиатурку на сферу. Тут я немного поэкспериментировал с дизерингом, и к Дизерингу Курильщика у меня добавился еще и Дизеринг Эпилептика.

uxbb_7fbr7fvyncq3-u2bjkk2u8.gif
Аналогично предыдущему, только для CGA

© Habrahabr.ru