Keystick GUI

Обсуждение установки, настройки и использования LinuxCNC. Вопросы по Gкоду.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Keystick GUI

Сообщение Nick »

asutpka писал(а):<stdin>:11: Pin 'timedelta.1.max ' does not exist
Странно, почему он у тебя на эти пины ругается...

попробуй выполнить в halrun:

Код: Выделить всё

loadrt timedelta count=2
show
и вывод сюда...
asutpka писал(а):Ник перенеси посты 9,10,,12,13,14,,16,17,18,19,20, сюда так правильней будет. И афтаеву скоро пригодится.
Не, так получится рваное обсуждение, лучше в той теме просто напиши ссылку сюда...
asutpka
Мастер
Сообщения: 294
Зарегистрирован: 17 апр 2013, 14:27
Репутация: 78
Контактная информация:

Re: Keystick GUI

Сообщение asutpka »

Nick писал(а):и вывод сюда..

Код: Выделить всё

linuxcnc@arm:~$ halrun
rtapi:0 stopped
msgd:0 stopped
halcmd: loadrt timedelta count=2
halcmd: show
Loaded HAL Components:
ID      Type  Name                                      PID   State
     4  RT    timedelta                                       ready
     1  User  halcmd3316                                 3316 ready

Component Pins:
Owner   Type  Dir         Value  Name	Epsilon		Flags
     4  float OUT             0  timedelta.0.avg-err	0.000000	0
     4  s32   OUT             0  timedelta.0.err	0.000000	0
     4  s32   OUT             0  timedelta.0.jitter	0.000000	0
     4  s32   OUT             0  timedelta.0.max	0.000000	0
     4  s32   OUT             0  timedelta.0.min	0.000000	0
     4  s32   OUT             0  timedelta.0.out	0.000000	0
     4  bit   IN          FALSE  timedelta.0.reset	0.000000	0
     4  float OUT             0  timedelta.1.avg-err	0.000000	0
     4  s32   OUT             0  timedelta.1.err	0.000000	0
     4  s32   OUT             0  timedelta.1.jitter	0.000000	0
     4  s32   OUT             0  timedelta.1.max	0.000000	0
     4  s32   OUT             0  timedelta.1.min	0.000000	0
     4  s32   OUT             0  timedelta.1.out	0.000000	0
     4  bit   IN          FALSE  timedelta.1.reset	0.000000	0

Pin Aliases:
 Alias                                      Original Name

Signals:
Type          Value  Name     (linked to)

Parameters:
Owner   Type  Dir         Value  Name
     4  s32   RO              0  timedelta.0.time
     4  s32   RW              0  timedelta.0.tmax
     4  s32   RO              0  timedelta.1.time
     4  s32   RW              0  timedelta.1.tmax

Parameter Aliases:
 Alias                                      Original Name

Exported Functions:
Owner   CodeAddr  Arg       FP   Users  Name
 00004  b6c26941  b6c2f3c0  NO       0   timedelta.0
 00004  b6c26941  b6c2f3f0  NO       0   timedelta.1

Realtime Threads (flavor: xenomai) :
     Period  FP     Name               (     Time, Max-Time )

halcmd: ^Clinuxcnc@arm:~$ 
nkp
Мастер
Сообщения: 8340
Зарегистрирован: 28 ноя 2011, 00:25
Репутация: 1589
Контактная информация:

Re: Keystick GUI

Сообщение nkp »

я не знаю в чем причина - но заметил , что у тебя в ошибке:
<stdin>:11: Pin 'timedelta.1.max ' does not exist
а вообще то должно быть:
<stdin>:11: Pin 'timedelta.1.max' does not exist
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Keystick GUI

Сообщение Nick »

странно...вроде все так... попробуй может лишний пробел убрать, хотя он тут не должен влиять...

сейчас у себя еще раз попробовал - работает...
asutpka
Мастер
Сообщения: 294
Зарегистрирован: 17 апр 2013, 14:27
Репутация: 78
Контактная информация:

Re: Keystick GUI

Сообщение asutpka »

Всё правильно
пробел был лишним
без него
(для просмотра содержимого нажмите на ссылку)

Код: Выделить всё

linuxcnc@arm:~$ halrun
rtapi:0 stopped
msgd:0 stopped
halcmd: loadrt threads name1=fast period1=30000 name2=slow period2=1000000 name3=sample period3=1000000000
halcmd: loadrt timedelta count=2
halcmd: addf timedelta.0 fast
halcmd: addf timedelta.1 slow
halcmd: loadrt sampler depth=1000 cfg="SSSSSS"
halcmd: loadusr halsampler
halcmd: addf sampler.0 sample
halcmd: net sl timedelta.1.max => sampler.0.pin.0
halcmd: net sj timedelta.1.jitter => sampler.0.pin.1
halcmd: net st timedelta.1.out => sampler.0.pin.2
halcmd: net bl timedelta.0.max => sampler.0.pin.3
halcmd: net bj timedelta.0.jitter => sampler.0.pin.4
halcmd: net bt timedelta.0.out => sampler.0.pin.5
halcmd: # All times are in ns
halcmd: #  Servo thread  |  Base thread
halcmd: #MaxInt|MaxJitt|LastInt|MaxInt|MaxJitt|LastInt
halcmd: start
halcmd: 1021667 543666 989958 236375 206375 28541 
1022208 543666 989917 236375 206375 28458 
1022208 543666 989125 236375 206375 28375 
1022208 543666 990459 236375 206375 29208 
1022208 543666 989833 236375 206375 29209 
1022208 543666 987792 236375 206375 30334 
1022417 543666 989208 236375 206375 28792 
1022417 543666 989625 236375 206375 28959 
1022500 543666 986208 236375 206375 33666 
1023083 543666 1018958 236375 206375 29875 
1023083 543666 989625 236375 206375 28583 
1023083 543666 990708 236375 206375 30959 
1023083 543666 989375 236375 206375 28542 
1023083 543666 990375 236375 206375 28458 
1023083 543666 990042 236375 206375 29083 
1023083 543666 1016625 236375 206375 29000 
1023083 543666 991250 236375 206375 29375 
1023083 543666 989917 236375 206375 29083 
1023083 543666 990416 236375 206375 28250 
1023083 543666 987209 236375 206375 29417 
1023083 543666 1017291 236375 206375 30709 
1023083 543666 990208 236375 206375 28917 
^C
linuxcnc@arm:~$
И это следствие моей невнимательности. При редактировании первой строки мне удобней было загрузить весь текст в тексовый редактор , который в сою очередь и заменил TAB на пробел. Он наказан.


Добавлю. Нагрузить в таком режиме нет никакой возможности, поскольку ничего в этот момент внятно не запускается, но если period1=32768 и больше - кое-что начинает запускаться. Сам по себе halsampler являлся серьёзной нагрузкой.
например запустил htop для контроля и apt-get
1.png (4625 просмотров) <a class='original' href='./download/file.php?id=24158&sid=ba8da157ee7ee042ddc290bbe0025aa6&mode=view' target=_blank>Загрузить оригинал (84.7 КБ)</a>
Очень медленно работало всё, то есть aptget минуты 4 делал то, что должен был сделать в считаные секунды.Показания были в тот момент такими -
(для просмотра содержимого нажмите на ссылку)

Код: Выделить всё

MaxInt|MaxJitt|LastInt|MaxInt|MaxJitt|LastInt
1078084 62578 1015292 283875 251105 32417 
1078084 62578 1016625 283875 251105 27167 
1078084 62578 1013750 283875 251105 27917 
1078084 62578 1017042 283875 251105 36625 
1078084 62578 1015708 283875 251105 26125 
1078084 62578 1009083 283875 251105 29917 
1078084 62578 1043458 283875 251105 28834 
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Keystick GUI

Сообщение Nick »

Вот это мне не нравится: MaxJitt = 251105...
250000 это слишком много... с новым ядром стало лучше?
asutpka
Мастер
Сообщения: 294
Зарегистрирован: 17 апр 2013, 14:27
Репутация: 78
Контактная информация:

Re: Keystick GUI

Сообщение asutpka »

Nick писал(а): с новым ядромстало лучше?
С новым ядром latency-test-cli работает в исходном варианте period1=25000 точно так-же как и halrun команды.
(для просмотра содержимого нажмите на ссылку)

Код: Выделить всё

#первый запуск
linuxcnc@arm:~$ ./latency-test-cli
rtapi:0 stopped
msgd:0 stopped
All times are in ns
                  Servo thread       |                   Base thread       
Max Interv | Max Jitter | Last inter | Max Interv | Max Jitter | Last inter
   1003958 |      21167 |    1001958 |      33458 |      20917 |      25750
   1003958 |      21167 |    1001250 |      33458 |      20917 |      24459
   1003958 |      21167 |    1001417 |      33458 |      20917 |      24334
  ^C
#второй запуск
linuxcnc@arm:~$ ./latency-test-cli
rtapi:0 stopped
msgd:0 stopped
All times are in ns
                  Servo thread       |                   Base thread       
Max Interv | Max Jitter | Last inter | Max Interv | Max Jitter | Last inter
 
   1006292 |       8083 |    1006292 |      33584 |      13834 |      25042
   1006292 |       8083 |    1006041 |      33584 |      13834 |      24917
   1006292 |       8083 |    1002250 |      33584 |      13834 |      24708
   1006292 |       8083 |     999916 |      33584 |      13834 |      24917
   1006292 |       8083 |    1001541 |      33584 |      13834 |      25375
   1006292 |       8083 |    1000042 |      33584 |      13834 |      25000
   1006292 |       8083 |    1000083 |      33750 |      13834 |      24834
   1006292 |       8083 |     999875 |      33750 |      13834 |      25041
   1008208 |       8208 |    1001292 |      33750 |      13834 |      24625
   1008208 |       8208 |    1001333 |      33750 |      13834 |      24958
   1008208 |       8208 |    1001000 |      68459 |      43459 |      24792
   1008208 |       8208 |    1001417 |      68459 |      43459 |      25041
   1008208 |       8208 |     999958 |      68459 |      43459 |      24917
   1008208 |       8208 |    1000083 |      68459 |      43459 |      25625
   1008208 |       8208 |     999959 |      68459 |      43459 |      25042
   1008208 |       8208 |    1001125 |      68459 |      43459 |      24833
 #нагрузил распаковкой 15 мегабайтного архива
   1009541 |       9541 |    1000084 |      68459 |      43459 |      25334
   1010584 |      10584 |    1001958 |      68459 |      43459 |      25250
   1010584 |      10584 |    1000750 |      68459 |      43459 |      25125
   1012541 |      12541 |    1000291 |      68459 |      43459 |      25000
   1012541 |      12541 |    1001333 |      68459 |      43459 |      24834
   1012541 |      12541 |     998958 |      68459 |      43459 |      25167
   1012541 |      12541 |    1002083 |      70958 |      45958 |      25208
   1012541 |      12541 |    1001208 |      71708 |      46708 |      25083
   1012541 |      12541 |    1000208 |      71708 |      46708 |      24541
   1012541 |      12541 |     998125 |      71708 |      46708 |      24709
   1012541 |      12541 |    1000083 |      71708 |      46708 |      25250
   1012541 |      12541 |     995375 |      71708 |      46708 |      25041
   1012541 |      12541 |     996791 |      71708 |      46708 |      24875
   1012541 |      12541 |     999625 |      71708 |      46708 |      24750
   1012541 |      12541 |     999375 |      71708 |      46708 |      25042
   1012541 |      12541 |    1000042 |      71708 |      46708 |      25042
   1012541 |      12541 |     998625 |      71708 |      46708 |      28583
   1026708 |      26708 |     996458 |      71708 |      46708 |      24667
   1026708 |      26708 |     999084 |      71708 |      46708 |      24666
   1026708 |      26708 |     993958 |      71708 |      46708 |      25000
   1026708 |      26708 |     999458 |      71708 |      46708 |      25042
   1026708 |      26708 |    1000041 |      71708 |      46708 |      25167
   1026708 |      26708 |     997875 |      71708 |      46708 |      24708
   1026708 |      26708 |     999584 |      71708 |      46708 |      25042
   1026708 |      26708 |    1001417 |      71708 |      46708 |      24708
   1026708 |      26708 |     998458 |      71708 |      46708 |      25708
   1026708 |      26708 |     998958 |      71708 |      46708 |      24625
   1026750 |      27625 |    1004500 |      71708 |      46708 |      25291
   1026750 |      27625 |    1005708 |      71708 |      46708 |      25125
   1026750 |      27625 |     999459 |      71708 |      46708 |      24750
   1026750 |      27625 |    1000208 |      71708 |      46708 |      25333
   1026750 |      27625 |     998750 |      71708 |      46708 |      24708
   1026750 |      27625 |    1003125 |      71708 |      46708 |      25042
   1026750 |      27625 |     994917 |      71708 |      46708 |      25583
   1026750 |      27625 |    1000083 |      71708 |      46708 |      25042
   1026750 |      27625 |    1001416 |      71708 |      46708 |      24750
   1026750 |      27625 |     999667 |      71708 |      46708 |      24875
   1026750 |      27625 |     999166 |      71708 |      46708 |      24917
   1026750 |      27625 |    1001750 |      71708 |      46708 |      24709
   1026750 |      27625 |     998625 |      71708 |      46708 |      24875
   
^Clinuxcnc@arm:~$
(для просмотра содержимого нажмите на ссылку)

Код: Выделить всё

linuxcnc@arm:~$ halrun
rtapi:0 stopped
msgd:0 stopped
halcmd: loadrt threads name1=fast period1=25000 name2=slow period2=1000000 name3=sample period3=1000000000
halcmd: 
halcmd: loadrt timedelta count=2
halcmd: addf timedelta.0 fast
halcmd: addf timedelta.1 slow
halcmd: 
halcmd: loadrt sampler depth=1000 cfg="SSSSSS"
halcmd: loadusr halsampler
halcmd: addf sampler.0 sample
halcmd: 
halcmd: net sl timedelta.1.max      => sampler.0.pin.0
halcmd: net sj timedelta.1.jitter   => sampler.0.pin.1
halcmd: net st timedelta.1.out      => sampler.0.pin.2
halcmd: net bl timedelta.0.max      => sampler.0.pin.3
halcmd: net bj timedelta.0.jitter   => sampler.0.pin.4
halcmd: net bt timedelta.0.out      => sampler.0.pin.5
halcmd: # All times are in ns
halcmd: #     Servo thread     |    Base thread
halcmd: #MaxInt|MaxJitt|LastInt|MaxInt|MaxJitt|LastInt
halcmd: start
halcmd: 1015583 15625 1000000 202875 177875 25000 
1015583 16458 999958 202875 177875 24417 
1016125 16458 1000583 202875 177875 24042 
1016125 16458 1000041 202875 177875 24417 
1016125 16458 986292 202875 177875 16333 
1019125 20000 1013167 202875 177875 17000 
1019125 20000 1000000 202875 177875 24708 
1019125 20000 1000084 202875 177875 24541 
1019125 20000 1013334 202875 177875 16375 
1019125 20000 1013667 202875 177875 16583 
1019208 20000 1000208 202875 177875 17166 
1019958 20000 1000708 202875 177875 24709 
1019958 20000 985500 202875 177875 17292 
1019958 20000 1001792 202875 177875 17125 
1019958 20000 1000416 202875 177875 17000 
1019958 20000 997375 202875 177875 17542 
1019958 20000 1014625 202875 177875 16834 
1020250 20250 1001084 202875 177875 17458 
1020250 20250 1014250 202875 177875 23958 
1021542 21542 1000709 202875 177875 16792 
1021542 21542 1013542 202875 177875 16000 
1021542 21542 1000209 202875 177875 16583 
^Clinuxcnc@arm:~$
Насчёт хорошо это или плохо - у меня своих суждений нет.
Дольше пока не тестировал на основной работе завал.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Keystick GUI

Сообщение Nick »

На втором запуске какой-то скачек... с 13000 до 43000...
Странно, что в варианте через halrun сразу показывает большой jitter - за 150 000...
asutpka
Мастер
Сообщения: 294
Зарегистрирован: 17 апр 2013, 14:27
Репутация: 78
Контактная информация:

Re: Keystick GUI

Сообщение asutpka »

Nick писал(а):На втором запуске какой-то скачек... с 13000 до 43000
Этот скачек обусловлен тем, что в это время я подключал ещё один терминал по SSH
Остальное для меня пока необъяснима, однако могу предположить, что команда start инициирует чтение какого либо файла с флеш а скорость может быть крайне невысока.
Аватара пользователя
Nick
Мастер
Сообщения: 22776
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1735
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Keystick GUI

Сообщение Nick »

можно попробовать сбросить значения из отдельного терминала:

Код: Выделить всё

halcmd setp timedelta.0.reset 1
halcmd setp timedelta.0.reset 0
halcmd setp timedelta.1.reset 1
halcmd setp timedelta.1.reset 0
Если при подключении нового терминала проходит такой скачек - то это ничего хорошего не сулит, если во время работы станка подключишь еще один терминал - станок может лагануть...
asutpka
Мастер
Сообщения: 294
Зарегистрирован: 17 апр 2013, 14:27
Репутация: 78
Контактная информация:

Re: Keystick GUI

Сообщение asutpka »

Сброситил значения из отдельного терминала
(для просмотра содержимого нажмите на ссылку)

Код: Выделить всё

halcmd: start
#     Servo thread     |    Base thread
#MaxInt|MaxJitt|LastInt|MaxInt|MaxJitt|LastInt
1017042 17042 1000250 112541 87541 17792 
1017042 17042 1000000 112541 87541 17750 
1017042 17042 999833 112541 87541 18167 
1017042 17042 999958 112541 87541 17750 
1017042 17042 999750 112541 87541 17250 
1017042 17042 1000083 112541 87541 17584 
1017042 17042 999875 112541 87541 17916 
1017042 17042 1000042 112541 87541 18166 
1017042 17042 1000042 112541 87541 17625 
1017042 17042 999750 112541 87541 16916 
1017042 17042 999958 112541 87541 18875 
сбросил
0 0 0 34208 9458 17541 
1014250 14375 1000000 34542 9542 18084 
1016375 16375 999833 34542 9542 17916 
1016375 16375 986291 34542 9542 17334 
1016375 16375 999958 34542 9542 18333 
1016375 16375 999875 34542 9542 17750 
1016375 16375 1013708 34542 9542 16916 
1017458 17458 1000125 34542 9542 17584 
1017458 17458 998375 34542 9542 17208 
1017458 17458 999917 34542 9542 18375 
1017458 17458 1013458 34542 9542 17125 
запустил midnight commander
1017458 17458 1013542 35584 11625 17875 
1017458 17458 986917 35584 11625 17542 
1017458 17458 1000041 35584 11625 17667 
1017458 17458 999958 35584 11625 18209 
1017458 17458 1000459 35584 11625 17583 
1017458 17458 1014750 35584 11625 17000 
1017458 17458 1000041 36042 12000 18000 
1017458 17458 999375 37458 12458 17125 
1017458 17542 998542 37458 12458 17584 
1017750 17750 998292 39292 16125 17708 
1017750 17750 1003375 39292 16125 18083 
запустил распаковку 15 мегабайтного архива
точнее дал команду midnight commander
покажи ка что внутри deb файла размером в 15 мегабайт
контролируя загрузку процессора htop в третьем терминале
загрузка 100%
1018000 18000 987083 44833 20458 17208 
1019958 19958 1000625 67458 42458 17833 
1019958 19958 1005667 67458 42458 18042 
1019958 19958 999875 67458 42458 17458 
1019958 19958 1000417 67458 42458 18000 
1019958 19958 1000167 67458 42458 17417 
1019958 19958 999333 67458 42458 17375 
1019958 19958 1001542 67458 42458 17625 
1019958 19958 999875 67458 42458 16459 
^Clinuxcnc@arm:~$ 
Kovus2
Мастер
Сообщения: 221
Зарегистрирован: 23 авг 2018, 11:52
Репутация: 35
Настоящее имя: Олег
Откуда: Минск
Контактная информация:

Re: Keystick GUI

Сообщение Kovus2 »

Возможно ли получить уже пропатченый исходник?
Хотел бы попытаться внедрить его в сборку для платы Orange Pi PC.
Пробовал сам пропатчить, но вот что получаю:

Код: Выделить всё

kovus@Kroha ~/Загрузки/keystick $ patch keystick.cc < keystick.patch 
patching file keystick.cc
patch unexpectedly ends in middle of line
Hunk #29 succeeded at 2969 with fuzz 1.
Или это исходник правильно пропатчился?
asutpka
Мастер
Сообщения: 294
Зарегистрирован: 17 апр 2013, 14:27
Репутация: 78
Контактная информация:

Re: Keystick GUI

Сообщение asutpka »

У меня с тем-же матюгом получилось это
(для просмотра содержимого нажмите на ссылку)
/********************************************************************
* Description: keystick.cc
* Curses-based keyboard control panel
*
* Derived from a work by Fred Proctor & Will Shackleford
*
* Author:
* License: GPL Version 2
* System: Linux
*
* Copyright (c) 2004 All rights reserved.
*
* Last change:
********************************************************************/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <signal.h>
#include <errno.h>
#include <sys/time.h> // struct itimerval
#include <sys/ioctl.h> // ioctl(), TIOCGWINSZ, struct winsize
#include <unistd.h> // STDIN_FILENO

#include "rcs.hh" // rcs_print_error(), esleep()
#include "emc.hh" // EMC NML
#include "emc_nml.hh"
#include "emcglb.h" // EMC_NMLFILE, TRAJ_MAX_VELOCITY
#include "emccfg.h" // DEFAULT_TRAJ_MAX_VELOCITY
#include "inifile.hh" // INIFILE
#include "rcs_print.hh"
#include "nml_oi.hh"
#include "timer.hh"

#include <ncurses.h>
#define ESC 27
#define TAB 9
#define RETURN 13
#define ALT(ch) ((ch) + 128)
#define CTL(ch) ((ch) - 64)

// paths to awk and xgraph, using to plot logs
// fill these in for your system, if these are not in user's path
#define AWK_PATH "awk"
#define XGRAPH_PATH "xgraph"
#define SYSTEM_STRING_LEN 1024


// the NML channels to the EMC task
static RCS_CMD_CHANNEL *emcCommandBuffer = 0;
static RCS_STAT_CHANNEL *emcStatusBuffer = 0;
EMC_STAT *emcStatus = 0;

// the NML channel for errors
static NML *emcErrorBuffer = 0;
static char error_string[NML_ERROR_LEN] = "";

// the current command numbers, set up updateStatus(), used in main()
static int emcCommandSerialNumber = 0;

// NML messages
static EMC_AXIS_HOME emc_axis_home_msg;
static EMC_AXIS_ABORT emc_axis_abort_msg;
static EMC_AXIS_JOG emc_axis_jog_msg;
static EMC_AXIS_INCR_JOG emc_axis_incr_jog_msg;
static EMC_TRAJ_SET_SCALE emc_traj_set_scale_msg;
static EMC_TRAJ_ABORT emc_traj_abort_msg;
static EMC_SPINDLE_ON emc_spindle_on_msg;
static EMC_SPINDLE_OFF emc_spindle_off_msg;
static EMC_SPINDLE_INCREASE emc_spindle_increase_msg;
static EMC_SPINDLE_DECREASE emc_spindle_decrease_msg;
static EMC_SPINDLE_CONSTANT emc_spindle_constant_msg;
static EMC_SPINDLE_BRAKE_RELEASE emc_spindle_brake_release_msg;
static EMC_SPINDLE_BRAKE_ENGAGE emc_spindle_brake_engage_msg;
static EMC_COOLANT_MIST_ON emc_coolant_mist_on_msg;
static EMC_COOLANT_MIST_OFF emc_coolant_mist_off_msg;
static EMC_COOLANT_FLOOD_ON emc_coolant_flood_on_msg;
static EMC_COOLANT_FLOOD_OFF emc_coolant_flood_off_msg;
static EMC_LUBE_ON emc_lube_on_msg;
static EMC_LUBE_OFF emc_lube_off_msg;
static EMC_TOOL_LOAD_TOOL_TABLE emc_tool_load_tool_table_msg;
static EMC_TASK_SET_MODE mode_msg;
static EMC_TASK_SET_STATE state_msg;
static EMC_TASK_ABORT task_abort_msg;
static EMC_TASK_PLAN_INIT task_plan_init_msg;
static EMC_TASK_PLAN_OPEN task_plan_open_msg;
static EMC_TASK_PLAN_RUN task_plan_run_msg;
static EMC_TASK_PLAN_EXECUTE task_plan_execute_msg;
static EMC_TASK_PLAN_PAUSE task_plan_pause_msg;
static EMC_TASK_PLAN_RESUME task_plan_resume_msg;
static EMC_TASK_PLAN_STEP task_plan_step_msg;

// critical section flag-- set to non-zero to prevent sig handler
// from interrupting your window printing
static unsigned char critFlag = 0;

// the program path prefix
static char programPrefix[LINELEN] = "";
// the saved program name
static char programFile[LINELEN] = "";
static int programOpened = 0;
static FILE * programFp = 0;
static int programFpLine = 0;
static int programActiveLine = 0;
static char programLineText[LINELEN] = "";


// error log file
static FILE *errorFp = NULL;
#define ERROR_FILE "keystick.err"

typedef enum {
JOG_CONTINUOUS = 1,
JOG_INCREMENTAL
} JOG_MODE;

static JOG_MODE jogMode
= JOG_CONTINUOUS;
static double jogIncrement = 0.001;
static double jogSpeed = 60.0;

static int xJogPol = 1;
static int yJogPol = 1;
static int zJogPol = 1;
static int aJogPol = 1;

typedef enum {
AXIS_NONE = 1,
AXIS_X,
AXIS_Y,
AXIS_Z,
AXIS_A,
} AXIS_TYPE;

static AXIS_TYPE axisSelected = AXIS_X;
static AXIS_TYPE axisJogging = AXIS_NONE;

static const char * axisString(AXIS_TYPE a)
{
switch (a)
{
case AXIS_X:
return " X SELECTED ";
case AXIS_Y:
return " Y SELECTED ";
case AXIS_Z:
return " Z SELECTED ";
case AXIS_A:
return " A SELECTED ";

default:
return " ? SELECTED ";
}
}

static int axisIndex(AXIS_TYPE a)
{
if (a == AXIS_X)
return 0;
if (a == AXIS_Y)
return 1;
if (a == AXIS_Z)
return 2;
if (a == AXIS_A)
return 3;

return 0;
}

typedef enum {
COORD_RELATIVE = 1,
COORD_ABSOLUTE
} COORD_TYPE;

static COORD_TYPE coords = COORD_RELATIVE;

typedef enum {
POS_DISPLAY_ACT = 1,
POS_DISPLAY_CMD
} POS_DISPLAY_TYPE;

static POS_DISPLAY_TYPE posDisplay = POS_DISPLAY_ACT;

static int spindleChanging = 0;

#define INTERRUPT_USECS 50000
static int usecs = INTERRUPT_USECS;

static chtype ch = 0, oldch = 0;

#define ASCLINELEN 80
static char line_blank[ASCLINELEN + 1];

static char scratch_string[ASCLINELEN] = "";
static char state_string[ASCLINELEN] = "";
static char mode_string[ASCLINELEN] = "";
static char spindle_string[ASCLINELEN] = "";
static char brake_string[ASCLINELEN] = "";
static char mist_string[ASCLINELEN] = "";
static char flood_string[ASCLINELEN] = "";
static char lube_on_string[ASCLINELEN] = "";
static char lube_level_string[ASCLINELEN] = "";
static char home_string[ASCLINELEN] = "";
static char pos_string[ASCLINELEN] = "";
static char origin_string[ASCLINELEN] = "";
static char speed_string[ASCLINELEN] = "";
static char incr_string[ASCLINELEN] = "";
static char prog_string[ASCLINELEN] = "";
static char line_string[ASCLINELEN] = "";
static char interp_string[ASCLINELEN] = "";
static char active_g_codes_string[ASCLINELEN] = "";
static char active_m_codes_string[ASCLINELEN] = "";

// bottom string gill be set to "---Machine Version---"
static char bottom_string[ASCLINELEN + 1] = "";

// key repeat delays, in microseconds
#define DEFAULT_FIRST_KEYUP_DELAY 300000 // works w/ 50000 alarm
static int FIRST_KEYUP_DELAY = DEFAULT_FIRST_KEYUP_DELAY;
#define DEFAULT_NEXT_KEYUP_DELAY 100000 // works w/ 50000 alarm
static int NEXT_KEYUP_DELAY = DEFAULT_NEXT_KEYUP_DELAY;

static int keyup_count = 0;

static enum {DIAG_USECS = 1, DIAG_FIRST_KEYUP_DELAY, DIAG_NEXT_KEYUP_DELAY} diagtab = DIAG_USECS;

static WINDOW * window = 0;
static WINDOW * helpwin = 0;
static WINDOW * diagwin = 0;
static WINDOW * toolwin = 0;
static WINDOW * logwin = 0;
static WINDOW * progwin = 0;

static int wbegy, wbegx;
static int wmaxy, wmaxx;

static void printFkeys()
{ wattrset(window, A_BOLD);
mvwaddstr(window, 0, 1, "F1 ");
mvwaddstr(window, 1, 1, "F2 ");
mvwaddstr(window, 2, 1, "F3 ");
mvwaddstr(window, 3, 1, "F4 ");
mvwaddstr(window, 0, 21, "F5 ");
mvwaddstr(window, 1, 21, "F6 ");
mvwaddstr(window, 2, 21, "F7 ");
mvwaddstr(window, 3, 21, "F8 ");
mvwaddstr(window, 0, 41, "F9 ");
mvwaddstr(window, 1, 41, "F10");
mvwaddstr(window, 2, 41, "F11");
mvwaddstr(window, 3, 41, "F12");
mvwaddstr(window, 0, 61, "ESC");
mvwaddstr(window, 1, 61, "TAB");
mvwaddstr(window, 2, 61, "END");
mvwaddstr(window, 3, 61, " ? ");

wattrset(window, 0);
mvwaddstr(window, 0, 5, "Estop On/Off ");
mvwaddstr(window, 1, 5, "Machine On/Off");
mvwaddstr(window, 2, 5, "Manual Mode ");
mvwaddstr(window, 3, 5, "Auto Mode ");

mvwaddstr(window, 0, 25, "MDI Mode ");
mvwaddstr(window, 1, 25, "Reset Interp ");
mvwaddstr(window, 2, 25, "Mist On/Off ");
mvwaddstr(window, 3, 25, "Flood On/Off ");

mvwaddstr(window, 0, 45, "Spndl Fwd/Off ");
mvwaddstr(window, 1, 45, "Spndl Rev/Off ");
mvwaddstr(window, 2, 45, "Spndl Decrease");
mvwaddstr(window, 3, 45, "Spndl Increase");

mvwaddstr(window, 0, 65, "Aborts Actions");
mvwaddstr(window, 1, 65, "Selects Params");
mvwaddstr(window, 2, 65, "Quits Display ");
mvwaddstr(window, 3, 65, "Toggles Help ");
}
#define ERR_Y ((wmaxy) - 2)
#define ERR_X (wbegx)

static void clearWindow()
{
int t;

critFlag = 1;

wattrset(window, A_BOLD);
for (t = wbegy; t <= wmaxy; t++)
{
mvwaddstr(window, t, 0, line_blank);
}
wrefresh(window);

wattrset(window, 0);
for (t = wbegy; t <= wmaxy; t++)
{
mvwaddstr(window, t, 0, line_blank);
}
wmove(window, wmaxy, wbegx);
wrefresh(window);

critFlag = 0;
}

static void printError(const char * errstring)
{
int savey, savex;
chtype saveattr;

// log to error file
if (errorFp)
{
fprintf(errorFp, "%f\t%s\n", etime(), errstring);
}

if (0 == window)
{
// no window yet
return;
}

critFlag = 1;

getyx(window, savey, savex);
saveattr = getattrs(window);

mvwaddstr(window, ERR_Y, ERR_X, line_blank);
wattrset(window, A_BOLD);
mvwaddstr(window, ERR_Y, ERR_X, errstring);
(void)wattrset(window, (int) saveattr);
wmove(window, savey, savex);
wrefresh(window);

critFlag = 0;
}

static void printStatus()
{
//Кое что надо пораскрашивать
int savey, savex;
int t;
int line;
int override;
int len;
int code;

getyx(window, savey, savex);

if (window == helpwin)
{
printFkeys();

wattrset(window, 0);
mvwaddstr(window, 5, 1, "x/X y/Y z/Z a/A");
mvwaddstr(window, 6, 1, "HOME");
mvwaddstr(window, 7, 1, "< > or , .");
mvwaddstr(window, 8, 1, "1-9, 0");
mvwaddstr(window, 9, 1, "<- arrow keys ->");
mvwaddstr(window, 10, 1, "^ arrow keys V");
mvwaddstr(window, 11, 1, "PageUp/PageDown");
mvwaddstr(window, 12, 1, " + / - ");
mvwaddstr(window, 13, 1, "c/C");
mvwaddstr(window, 14, 1, "i/I");
mvwaddstr(window, 15, 1, "#");
mvwaddstr(window, 16, 1, "@");

wattrset(window, A_UNDERLINE);
mvwaddstr(window, 5, 19, "selects axis");
mvwaddstr(window, 6, 19, "homes selected axis");
mvwaddstr(window, 7, 19, "change jog speed");
mvwaddstr(window, 8, 19, "10%-90%, 100% feed");
mvwaddstr(window, 9, 19, "jog X");
mvwaddstr(window, 10, 19, "jog Y");
mvwaddstr(window, 11, 19, "jog Z");
mvwaddstr(window, 12, 19, "jog A");
mvwaddstr(window, 13, 19, "sets continuous jog");
mvwaddstr(window, 14, 19, "toggles incr jog");
mvwaddstr(window, 15, 19, "toggles abs/rel");
mvwaddstr(window, 16, 19, "toggles cmd/act");

wattrset(window, 0);
mvwaddstr(window, 5, 41, "B");
mvwaddstr(window, 6, 41, "b");
mvwaddstr(window, 7, 41, "o/O");
mvwaddstr(window, 8, 41, "r/R");
mvwaddstr(window, 9, 41, "p/P");
mvwaddstr(window, 10, 41, "s/S");
mvwaddstr(window, 11, 41, "quote/XYZAGM");
mvwaddstr(window, 12, 41, "l/L");
mvwaddstr(window, 13, 41, "u/U");

wattrset(window, A_UNDERLINE);
mvwaddstr(window, 5, 54, "turns spindle brake on");
mvwaddstr(window, 6, 54, "turns spindle brake off");
mvwaddstr(window, 7, 54, "prompts for program");
mvwaddstr(window, 8, 54, "runs selected program");
mvwaddstr(window, 9, 54, "pauses motion");
mvwaddstr(window, 10, 54, "starts motion again");
mvwaddstr(window, 11, 54, "prompts for MDI command");
mvwaddstr(window, 12, 54, "prompts for tool table");
mvwaddstr(window, 13, 54, "turns lube off/on");

if (error_string[0])
{
printError(error_string);
}

wattrset(window, A_REVERSE);
mvwaddstr(window, wmaxy - 1, wbegx, bottom_string);
wattrset(window, 0);

// restore cursor position
wmove(window, savey, savex);
wrefresh(window);
}
else if (window == diagwin)
{
wattrset(window, A_BOLD);
mvwaddstr(window, 0, 34, "Diagnostics");

wattrset(window, 0);
mvwaddstr(window, 2, 1, "Task Heartbeat/Cmd:");
mvwaddstr(window, 3, 1, "IO Heartbeat/Cmd:");
mvwaddstr(window, 4, 1, "Motion Heartbeat/Cmd:");

if (diagtab == DIAG_USECS)
wattrset(window, A_BOLD);
mvwaddstr(window, 6, 1, "Polling Period (usecs):");
wattrset(window, 0);
if (diagtab == DIAG_FIRST_KEYUP_DELAY)
wattrset(window, A_BOLD);
mvwaddstr(window, 7, 1, "Kbd Delay Until Repeat:");
wattrset(window, 0);
if (diagtab == DIAG_NEXT_KEYUP_DELAY)
wattrset(window, A_BOLD);
mvwaddstr(window, 8, 1, "Kbd Delay Between Repeats:");
wattrset(window, 0);

mvwaddstr(window, 10, 1, "Task Execution State:");

mvwaddstr(window, 12, 1, "Traj Scale:");
mvwaddstr(window, 13, 1, "X Scale:");
mvwaddstr(window, 14, 1, "Y Scale:");
mvwaddstr(window, 15, 1, "Z Scale:");
mvwaddstr(window, 15, 1, "A Scale:");

mvwaddstr(window, 17, 1, "V/Max V:");
mvwaddstr(window, 18, 1, "A/Max A:");

wattrset(window, A_UNDERLINE);

sprintf(scratch_string, "%10ld %10d %10d", emcStatus->task.heartbeat,
emcStatus->echo_serial_number,
emcStatus->status);
mvwaddstr(window, 2, 28, scratch_string);
sprintf(scratch_string, "%10ld %10d", emcStatus->io.heartbeat,
emcStatus->io.echo_serial_number);
mvwaddstr(window, 3, 28, scratch_string);
sprintf(scratch_string, "%10ld %10d", emcStatus->motion.heartbeat,
emcStatus->motion.echo_serial_number);
mvwaddstr(window, 4, 28, scratch_string);

sprintf(scratch_string, "%10d", usecs);
mvwaddstr(window, 6, 28, scratch_string);
sprintf(scratch_string, "%10d", FIRST_KEYUP_DELAY);
mvwaddstr(window, 7, 28, scratch_string);
sprintf(scratch_string, "%10d", NEXT_KEYUP_DELAY);
mvwaddstr(window, 8, 28, scratch_string);

sprintf(scratch_string, "%10d", emcStatus->task.execState);
mvwaddstr(window, 10, 28, scratch_string);

sprintf(scratch_string, "%10.3f", emcStatus->motion.traj.scale);
mvwaddstr(window, 12, 28, scratch_string);

sprintf(scratch_string, "%10.3f%10.3f",
emcStatus->motion.traj.velocity, emcStatus->motion.traj.maxVelocity);
mvwaddstr(window, 17, 28, scratch_string);
sprintf(scratch_string, "%10.3f%10.3f",
emcStatus->motion.traj.acceleration, emcStatus->motion.traj.maxAcceleration);
mvwaddstr(window, 18, 28, scratch_string);

wattrset(window, 0);
if (error_string[0])
{
printError(error_string);
}

wattrset(window, A_REVERSE);
mvwaddstr(window, wmaxy - 1, wbegx, bottom_string);
wattrset(window, 0);

// restore cursor position
wmove(window, savey, savex);
wrefresh(window);
}
else if (window == toolwin)
{
wattrset(window, A_BOLD);
mvwaddstr(window, 0, 34, "Tool Table");

wattrset(window, 0);
mvwaddstr(window, 2, 1, "Pocket ToolNo Length Diameter");

wattrset(window, A_UNDERLINE);
line = 4;
for (t = 0; t < CANON_POCKETS_MAX; t++)
{
/* if (emcStatus->io.tool.toolTable[t].toolno)*/
if (emcStatus->io.tool.toolTable[t].toolno != -1) /* AIKE */
{
//sprintf(scratch_string, "%4d%10d%10.4f%10.4f",
sprintf(scratch_string, "%2d%8d%11.4f%10.4f%13d%12.4f%12.4f",
t,
emcStatus->io.tool.toolTable[t].toolno,
emcStatus->io.tool.toolTable[t].offset.tran.z,
emcStatus->io.tool.toolTable[t].diameter,
//add nev
emcStatus->io.tool.toolTable[t].orientation,
emcStatus->io.tool.toolTable[t].frontangle,
emcStatus->io.tool.toolTable[t].backangle);
//end nev
mvwaddstr(window, line++, 3, scratch_string);
}
}

wattrset(window, 0);
if (error_string[0])
{
printError(error_string);
}

wattrset(window, A_REVERSE);
mvwaddstr(window, wmaxy - 1, wbegx, bottom_string);
wattrset(window, 0);

// restore cursor position
wmove(window, savey, savex);
wrefresh(window);
}
else if (window == progwin)
{
// start_color();
// init_pair(1, COLOR_YELLOW, COLOR_BLACK);
// init_pair(2, COLOR_WHITE, COLOR_GREEN);
// init_pair(3, COLOR_BLACK, COLOR_RED);

mvwaddstr(window, 0, 0, line_blank);
wattrset(window, A_BOLD);
if (emcStatus->task.file[0] == 0)
{
mvwaddstr(window, 0, 36, "(no program)");
}
else
{
mvwaddstr(window, 0, 36, emcStatus->task.file);
}
wattrset(window, 0);

if (emcStatus->task.currentLine > 0)
{
if (emcStatus->task.motionLine > 0 &&
emcStatus->task.motionLine < emcStatus->task.currentLine)
{
programActiveLine = emcStatus->task.motionLine;
}
else
{
programActiveLine = emcStatus->task.currentLine;
}

if (programFp)
{
if (programFpLine > programActiveLine)
{
rewind(programFp);
programFpLine = 0;
programLineText[0] = 0;
}

// fast forward over past lines
while (programFpLine < programActiveLine)
{
if (fgets(programLineText, LINELEN, programFp) != NULL)
programFpLine++;
}

// now we have the current line
wattrset(window, A_BOLD);
for (t = 0; t < 20; t++)
{
// knock off CR, LF
len = strlen(programLineText) - 1;
while (len >= 0)
{
if (isspace(programLineText[len]))
{
programLineText[len] = 0;
len--;
}
else
{
break;
}
}

// print this line
mvwaddstr(window, t+2, wbegx, line_blank);
mvwaddstr(window, t+2, wbegx, programLineText);
wattrset(window, 0);

// get the next line
if (fgets(programLineText, LINELEN, programFp))
{
programFpLine++;
}
else
{
// make it a blank line to clear any old stuff
strcpy(programLineText, line_blank);
}
}
}
else
{
programLineText[0] = 0;
}
}
else
{
programActiveLine = 0;
programLineText[0] = 0;
line_string[0] = 0;
}

wattrset(window, 0);
if (error_string[0])
{
printError(error_string);
}

wattrset(window, A_REVERSE);
mvwaddstr(window, wmaxy - 1, wbegx, bottom_string);
wattrset(window, 0);

// restore cursor position
wmove(window, savey, savex);
wrefresh(window);
}
else // if (window == stdscr)
{
// print the function key labels
printFkeys();

// print the status labels

wattrset(window, 0);

mvwaddstr(window, 6, 1, "Override:");
mvwaddstr(window, 7, 1, "Tool:");
mvwaddstr(window, 8, 1, "Offset:");

mvwaddstr(window, 7, 61, "Speed:");
mvwaddstr(window, 8, 61, "Incr: ");

strcpy(scratch_string, "--X--");
if (emcStatus->motion.axis[0].minHardLimit)
scratch_string[0] = '*';
if (emcStatus->motion.axis[0].minSoftLimit)
scratch_string[1] = '*';
if (emcStatus->motion.axis[0].maxSoftLimit)
scratch_string[3] = '*';
if (emcStatus->motion.axis[0].maxHardLimit)
scratch_string[4] = '*';
mvwaddstr(window, 10, 23, scratch_string);

strcpy(scratch_string, "--Y--");
if (emcStatus->motion.axis[1].minHardLimit)
scratch_string[0] = '*';
if (emcStatus->motion.axis[1].minSoftLimit)
scratch_string[1] = '*';
if (emcStatus->motion.axis[1].maxSoftLimit)
scratch_string[3] = '*';
if (emcStatus->motion.axis[1].maxHardLimit)
scratch_string[4] = '*';
mvwaddstr(window, 10, 39, scratch_string);

strcpy(scratch_string, "--Z--");
if (emcStatus->motion.axis[2].minHardLimit)
scratch_string[0] = '*';
if (emcStatus->motion.axis[2].minSoftLimit)
scratch_string[1] = '*';
if (emcStatus->motion.axis[2].maxSoftLimit)
scratch_string[3] = '*';
if (emcStatus->motion.axis[2].maxHardLimit)
scratch_string[4] = '*';
mvwaddstr(window, 10, 55, scratch_string);

strcpy(scratch_string, "--A--");
if (emcStatus->motion.axis[3].minHardLimit)
scratch_string[0] = '*';
if (emcStatus->motion.axis[3].minSoftLimit)
scratch_string[1] = '*';
if (emcStatus->motion.axis[3].maxSoftLimit)
scratch_string[3] = '*';
if (emcStatus->motion.axis[3].maxHardLimit)
scratch_string[4] = '*';
mvwaddstr(window, 10, 70, scratch_string);

if (coords == COORD_ABSOLUTE)
{
if (posDisplay == POS_DISPLAY_CMD)
{
mvwaddstr(window, 11, 1, "Absolute Cmd Pos:");
}
else
{
mvwaddstr(window, 11, 1, "Absolute Act Pos:");
}
mvwaddstr(window, 12, 0, line_blank);
}
else
{
coords = COORD_RELATIVE;
if (posDisplay == POS_DISPLAY_CMD)
{
mvwaddstr(window, 11, 1, "Relative Cmd Pos:");
}
else
{
mvwaddstr(window, 11, 1, "Relative Act Pos:");
}
}

mvwaddstr(window, 14, 0, line_blank);
mvwaddstr(window, 15, 0, line_blank);
mvwaddstr(window, 16, 0, line_blank);
mvwaddstr(window, 17, 0, line_blank);
mvwaddstr(window, 18, 0, line_blank);
mvwaddstr(window, 19, 0, line_blank);
if (emcStatus->task.mode == EMC_TASK_MODE_AUTO)
{
mvwaddstr(window, 14, 1, "Program:");
mvwaddstr(window, 15, 1, "Line:");
mvwaddstr(window, 16, 1, "Command:");
mvwaddstr(window, 17, 1, "Interpreter:");
mvwaddstr(window, 18, 1, "Modal G Codes:");
mvwaddstr(window, 19, 1, "Modal M Codes:");
}
else if (emcStatus->task.mode == EMC_TASK_MODE_MDI)
{
mvwaddstr(window, 16, 1, "Command:");
mvwaddstr(window, 17, 1, "Interpreter:");
mvwaddstr(window, 18, 1, "Modal G Codes:");
mvwaddstr(window, 19, 1, "Modal M Codes:");
}

// end of labels

// fill the status strings in

switch(emcStatus->task.state)
{

case EMC_TASK_STATE_OFF:
sprintf(state_string, " OFF ");
break;
case EMC_TASK_STATE_ON:
wattrset(window, COLOR_PAIR(2));
sprintf(state_string, " ON ");
wattrset(window, 0);
break;
case EMC_TASK_STATE_ESTOP:
sprintf(state_string, " ESTOP ");
break;
//Сделать красным мигающим
case EMC_TASK_STATE_ESTOP_RESET:
sprintf(state_string, " ESTOP RESET ");
break;
default:
sprintf(state_string, " ? ");
break;
}

switch(emcStatus->task.mode)
{
case EMC_TASK_MODE_MANUAL:
sprintf(mode_string, " MANUAL ");
break;
case EMC_TASK_MODE_AUTO:
sprintf(mode_string, " AUTO ");
break;
case EMC_TASK_MODE_MDI:
sprintf(mode_string, " MDI ");
break;
default:
sprintf(mode_string, " ? ");
break;
}

if (emcStatus->motion.spindle.increasing > 0)
sprintf(spindle_string, " SPINDLE INCREASE ");
else if (emcStatus->motion.spindle.increasing < 0)
sprintf(spindle_string, " SPINDLE DECREASE ");
else if (emcStatus->motion.spindle.direction > 0)
sprintf(spindle_string, " SPINDLE FORWARD ");
else if (emcStatus->motion.spindle.direction < 0)
sprintf(spindle_string, " SPINDLE REVERSE ");
else
sprintf(spindle_string, " SPINDLE STOPPED ");

if (emcStatus->motion.spindle.brake)
sprintf(brake_string, " BRAKE ON ");
else
sprintf(brake_string, " BRAKE OFF ");

if (emcStatus->io.coolant.mist)
sprintf(mist_string, " MIST ON ");
else
sprintf(mist_string, " MIST OFF ");

if (emcStatus->io.coolant.flood)
sprintf(flood_string, " FLOOD ON ");
else
sprintf(flood_string, " FLOOD OFF ");

if (emcStatus->io.lube.on)
sprintf(lube_on_string, " LUBE ON ");
else
sprintf(lube_on_string, " LUBE OFF ");

if (! emcStatus->io.lube.level)
sprintf(lube_level_string, " LUBE OK ");
else
sprintf(lube_level_string, " LUBE LOW ");

sprintf(home_string, " ---- HOMED ");
if (emcStatus->motion.axis[0].homed)
{
home_string[4] = 'X';
}
if (emcStatus->motion.axis[1].homed)
{
home_string[5] = 'Y';
}
if (emcStatus->motion.axis[2].homed)
{
home_string[6] = 'Z';
}
if (emcStatus->motion.axis[3].homed)
{
home_string[7] = 'A';
}

/* if (emcStatus->motion.axis[2].homed)
{
home_string[6] = 'A';
} здесь надо основательно повозиться*/
if (coords == COORD_ABSOLUTE)
{
if (posDisplay == POS_DISPLAY_ACT)
{
sprintf(pos_string, "%9.4f %14.4f %14.4f %14.4f",
emcStatus->motion.traj.actualPosition.tran.x,
emcStatus->motion.traj.actualPosition.tran.y,
emcStatus->motion.traj.actualPosition.tran.z,
emcStatus->motion.traj.actualPosition.a);
}
else
{
sprintf(pos_string, "%9.4f %14.4f %14.4f %14.4f",
emcStatus->motion.traj.position.tran.x,
emcStatus->motion.traj.position.tran.y,
emcStatus->motion.traj.position.tran.z,
emcStatus->motion.traj.position.a);
}
}
else
{
coords = COORD_RELATIVE;
if (posDisplay == POS_DISPLAY_ACT)
{
sprintf(pos_string, "%9.4f %14.4f %14.4f %14.4f",
emcStatus->motion.traj.actualPosition.tran.x - emcStatus->task.g5x_offset.tran.x - emcStatus->task.g92_offset.tran.x - emcStatus->task.toolOffset.tran.x,
emcStatus->motion.traj.actualPosition.tran.y - emcStatus->task.g5x_offset.tran.y - emcStatus->task.g92_offset.tran.x - emcStatus->task.toolOffset.tran.y,
emcStatus->motion.traj.actualPosition.tran.z - emcStatus->task.g5x_offset.tran.z - emcStatus->task.g92_offset.tran.x - emcStatus->task.toolOffset.tran.z,
emcStatus->motion.traj.actualPosition.a - emcStatus->task.g5x_offset.a - emcStatus->task.g92_offset.tran.x - emcStatus->task.toolOffset.a);
}
else
{
sprintf(pos_string, "%9.4f %14.4f %14.4f %14.4f",
emcStatus->motion.traj.position.tran.x - emcStatus->task.g5x_offset.tran.x - emcStatus->task.g92_offset.tran.x - emcStatus->task.toolOffset.tran.x,
emcStatus->motion.traj.position.tran.y - emcStatus->task.g5x_offset.tran.y - emcStatus->task.g92_offset.tran.x - emcStatus->task.toolOffset.tran.y,
emcStatus->motion.traj.position.tran.z - emcStatus->task.g5x_offset.tran.z - emcStatus->task.g92_offset.tran.x - emcStatus->task.toolOffset.tran.z,
emcStatus->motion.traj.position.a - emcStatus->task.g5x_offset.a - emcStatus->task.g92_offset.tran.x - emcStatus->task.toolOffset.a);
}
}

sprintf(origin_string, "%9.4f %14.4f %14.4f %14.4f",
emcStatus->task.g5x_offset.tran.x + emcStatus->task.g92_offset.tran.x,
emcStatus->task.g5x_offset.tran.y + emcStatus->task.g92_offset.tran.y,
emcStatus->task.g5x_offset.tran.z + emcStatus->task.g92_offset.tran.z,
emcStatus->task.g5x_offset.a + emcStatus->task.g92_offset.a);

sprintf(speed_string, "%10.1f", jogSpeed);
if (jogMode == JOG_INCREMENTAL)
{
sprintf(incr_string, "%10.4f", jogIncrement);
}
else
{
sprintf(incr_string, "continuous");
}

if (! programOpened)
{
// print the last one opened, since we'll send this by default
strcpy(prog_string, programFile);
}
else
{
// print the one the controller knows about
strcpy(prog_string, emcStatus->task.file);
}

if (emcStatus->task.currentLine > 0)
{
if (emcStatus->task.motionLine > 0 &&
emcStatus->task.motionLine < emcStatus->task.currentLine)
{
programActiveLine = emcStatus->task.motionLine;
}
else
{
programActiveLine = emcStatus->task.currentLine;
}
sprintf(line_string, "%d", programActiveLine);
if (programFp)
{
if (programFpLine > programActiveLine)
{
rewind(programFp);
programFpLine = 0;
programLineText[0] = 0;
}

// fast forward over past lines
while (programFpLine < programActiveLine)
{
if (fgets(programLineText, LINELEN, programFp) != NULL)
programFpLine++;
}

// now we have the current line
// knock off CR, LF
len = strlen(programLineText) - 1;
while (len >= 0)
{
if (isspace(programLineText[len]))
{
programLineText[len] = 0;
len--;
}
else
{
break;
}
}
}
else
{
programLineText[0] = 0;
}
}
else
{
programActiveLine = 0;
programLineText[0] = 0;
line_string[0] = 0;
}

switch (emcStatus->task.interpState)
// Надо раскрасить
{
case EMC_TASK_INTERP_IDLE:
sprintf(interp_string, "%s", "IDLE ");
break;
case EMC_TASK_INTERP_READING:
sprintf(interp_string, "%s", "RUNNING ");
break;
case EMC_TASK_INTERP_PAUSED:
sprintf(interp_string, "%s", "PAUSED ");
break;
case EMC_TASK_INTERP_WAITING:
sprintf(interp_string, "%s", "RUNNING ");
break;
default:
sprintf(interp_string, "%s", "? ");
break;
}

// fill in the active G codes
active_g_codes_string[0] = 0;
for (t = 1; t < ACTIVE_G_CODES; t++)
{
code = emcStatus->task.activeGCodes[t];
if (code == -1)
continue;
if (code % 10)
sprintf(scratch_string, "G%.1f ", (double) code / 10.0);
else
sprintf(scratch_string, "G%d ", code / 10);
strcat(active_g_codes_string, scratch_string);
}

// fill in the active M codes, settings too
active_m_codes_string[0] = 0;
for (t = 1; t < ACTIVE_M_CODES; t++)
{
code = emcStatus->task.activeMCodes[t];
if (code == -1)
continue;
sprintf(scratch_string, "M%d ", code);
strcat(active_m_codes_string, scratch_string);
}
sprintf(scratch_string, "F%.0f ", emcStatus->task.activeSettings[1]);
strcat(active_m_codes_string, scratch_string);
sprintf(scratch_string, "S%.0f ", emcStatus->task.activeSettings[2]);
strcat(active_m_codes_string, scratch_string);

// fill the screen in

override = (int) (emcStatus->motion.traj.scale * 100.0 + 0.5);
sprintf(scratch_string, "%4d%%", override);
if (override < 100)
wattrset(window, A_BOLD);
else
start_color();
wattrset(window, A_UNDERLINE);
mvwaddstr(window, 6, 14, scratch_string);

sprintf(scratch_string, "%8d", emcStatus->io.tool.toolInSpindle);
wattrset(window, A_UNDERLINE);
mvwaddstr(window, 7, 11, scratch_string);

sprintf(scratch_string, "%8.4f", emcStatus->task.toolOffset.tran.z);
wattrset(window, A_UNDERLINE);
mvwaddstr(window, 8, 11, scratch_string);

wattrset(window, A_REVERSE);
mvwaddstr(window, 5, 1, state_string);
mvwaddstr(window, 5, 21, mode_string);
mvwaddstr(window, 6, 21, lube_on_string);
mvwaddstr(window, 7, 21, lube_level_string);
mvwaddstr(window, 5, 41, spindle_string);
mvwaddstr(window, 6, 41, brake_string);
mvwaddstr(window, 7, 41, mist_string);
mvwaddstr(window, 8, 41, flood_string);
mvwaddstr(window, 5, 61, home_string);
mvwaddstr(window, 6, 61, axisString(axisSelected));

wattrset(window, A_UNDERLINE);

mvwaddstr(window, 11, 21, pos_string);

if (coords == COORD_RELATIVE)
{
wattrset(window, 0);
mvwaddstr(window, 12, 21, origin_string);
}

wattrset(window, A_UNDERLINE);

mvwaddstr(window, 7, 69, speed_string);
mvwaddstr(window, 8, 69, incr_string);

if (emcStatus->task.mode == EMC_TASK_MODE_AUTO)
{
mvwaddstr(window, 14, 21, prog_string);
mvwaddstr(window, 15, 21, line_string);
if (emcStatus->task.interpState == EMC_TASK_INTERP_PAUSED)
wattrset(window, A_BOLD);
mvwaddstr(window, 16, 21, programLineText);
mvwaddstr(window, 17, 21, interp_string);
wattrset(window, A_UNDERLINE);
mvwaddstr(window, 18, 21, active_g_codes_string);
mvwaddstr(window, 19, 21, active_m_codes_string);
}
else if (emcStatus->task.mode == EMC_TASK_MODE_MDI)
{
if (emcStatus->task.interpState == EMC_TASK_INTERP_PAUSED)
wattrset(window, A_BOLD);
mvwaddstr(window, 16, 21, emcStatus->task.command);
mvwaddstr(window, 17, 21, interp_string);
wattrset(window, A_UNDERLINE);
mvwaddstr(window, 18, 21, active_g_codes_string);
mvwaddstr(window, 19, 21, active_m_codes_string);
}

if (error_string[0])
{
printError(error_string);
}

wattrset(window, A_REVERSE);
mvwaddstr(window, wmaxy - 1, wbegx, bottom_string);
wattrset(window, 0);

// restore cursor position
wmove(window, savey, savex);
wrefresh(window);
}
}

static int catchErrors = 1;

static int updateStatus()
{
NMLTYPE type;

if (0 == emcStatus ||
0 == emcStatusBuffer ||
! emcStatusBuffer->valid())
{
return -1;
}

if (catchErrors)
{
if (0 == emcErrorBuffer ||
! emcErrorBuffer->valid())
{
return -1;
}
}

switch (type = emcStatusBuffer->peek())
{
case -1:
// error on CMS channel
return -1;
break;

case 0: // no new data
case EMC_STAT_TYPE: // new data
// new data
break;

default:
return -1;
break;
}

if (catchErrors)
{
switch (type = emcErrorBuffer->read())
{
case -1:
// error reading channel
break;

case 0:
// nothing new
error_string[0] = 0;
break;

case EMC_OPERATOR_ERROR_TYPE:
strncpy(error_string,
((EMC_OPERATOR_ERROR *) (emcErrorBuffer->get_address()))->error,
LINELEN - 1);
error_string[LINELEN - 1] = 0;
break;

case EMC_OPERATOR_TEXT_TYPE:
strncpy(error_string,
((EMC_OPERATOR_TEXT *) (emcErrorBuffer->get_address()))->text,
LINELEN - 1);
error_string[LINELEN - 1] = 0;
break;

case EMC_OPERATOR_DISPLAY_TYPE:
strncpy(error_string,
((EMC_OPERATOR_DISPLAY *) (emcErrorBuffer->get_address()))->display,
LINELEN - 1);
error_string[LINELEN - 1] = 0;
break;


case NML_ERROR_TYPE:
strncpy(error_string,
((NML_ERROR *) (emcErrorBuffer->get_address()))->error,
NML_ERROR_LEN - 1);
error_string[NML_ERROR_LEN - 1] = 0;
break;

case NML_TEXT_TYPE:
strncpy(error_string,
((NML_TEXT *) (emcErrorBuffer->get_address()))->text,
NML_ERROR_LEN - 1);
error_string[NML_ERROR_LEN - 1] = 0;
break;

case NML_DISPLAY_TYPE:
strncpy(error_string,
((NML_DISPLAY *) (emcErrorBuffer->get_address()))->display,
NML_ERROR_LEN - 1);
error_string[NML_ERROR_LEN - 1] = 0;
break;

default:
strcpy(error_string, "unrecognized error");
break;
}
}

return 0;
}

/*
waits until the EMC reports that it's got the command with the
indicated serial_number. Sleeps between queries.
*/

#define EMC_COMMAND_TIMEOUT 1.0 // how long to wait until timeout
#define EMC_COMMAND_DELAY 0.1 // how long to sleep between checks

static int emcCommandWait(int serial_number)
{
double start = etime();

while (etime() - start < EMC_COMMAND_TIMEOUT)
{
updateStatus();

if (emcStatus->echo_serial_number == serial_number)
{
return 0;
}

esleep(EMC_COMMAND_DELAY);
}

printError("timeout sending command");

return -1;
}

/*
startTimer starts the timer to generate SIGALRM events, or stops the timer
if 'us' is 0. Enable a signal handler for SIGALRM before you call this.
*/
void startTimer(int us)
{
timeout(us < 1000 ? 1 : us/1000);
}

/*
idleHandler is called when no key is received after timeout and handles the
reading of NML status, the update of the status window, and key-up simulation
and handling
*/
static void idleHandler()
{
// read NML status
updateStatus();

// only print if main is not printing, so we don't clobber in the middle
if (! critFlag)
{
printStatus();
}

// simulate key-up event, as per comment below
keyup_count -= usecs;
if (keyup_count < 0)
{
keyup_count = 0;
/* oldch = 0;*/
ch = 0;
}

/*
Key-up events are simulated as follows: each time a key is received,
keyup_count is loaded. If it's a new key, FIRST_KEYUP_DELAY is
loaded. If it's the same as the last key, NEXT_KEYUP_DELAY is loaded.
This is to handle the different delay between the first and subsequent
repeats.

Each time through this handler, keyup_count is decremented. If it
reaches 0, it means no key has been pressed before the delay expires,
and we see this as a key-up event.

If you have code that needs to respond to a key-up event, set a flag
when you do your key-down stuff, and put the key-up code in here,
like this:

if (myFlag && keyup_count == 0)
{
// do stuff for key up here

// and clear your flag
myFlag = 0;
}
*/

// key up for jogs
if (axisJogging != AXIS_NONE && keyup_count == 0)
{
emc_axis_abort_msg.axis = axisIndex(axisJogging);
emc_axis_abort_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_axis_abort_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_NONE;
}

// key up for spindle speed changes
if (spindleChanging && keyup_count == 0)
{
emc_spindle_constant_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_constant_msg);
emcCommandWait(emcCommandSerialNumber);
spindleChanging = 0;
}
return;
}

static int done = 0;
static void quit(int sig)
{
// clean up curses windows
delwin(progwin);
progwin = 0;
delwin(logwin);
logwin = 0;
delwin(toolwin);
toolwin = 0;
delwin(diagwin);
diagwin = 0;
delwin(helpwin);
helpwin = 0;
endwin();

// clean up NML buffers

if (emcErrorBuffer)
{
delete emcErrorBuffer;
emcErrorBuffer = 0;
}

if (emcStatusBuffer)
{
delete emcStatusBuffer;
emcStatusBuffer = 0;
emcStatus = 0;
}

if (emcCommandBuffer)
{
delete emcCommandBuffer;
emcCommandBuffer = 0;
}

// close program file
if (programFp)
{
fclose(programFp);
programFp = 0;
}

// close error log file
if (errorFp)
{
fclose(errorFp);
errorFp = NULL;
}

// reset signal handlers to default
signal(SIGINT, SIG_DFL);

exit(0);
}

static int emcTaskNmlGet()
{
int retval = 0;

// try to connect to EMC cmd
if (emcCommandBuffer == 0)
{
emcCommandBuffer = new RCS_CMD_CHANNEL(emcFormat, "emcCommand", "keystick", EMC_NMLFILE);
if (! emcCommandBuffer->valid())
{
rcs_print_error("emcCommand buffer not available\n");
delete emcCommandBuffer;
emcCommandBuffer = 0;
retval = -1;
}
}

// try to connect to EMC status
if (emcStatusBuffer == 0)
{
emcStatusBuffer = new RCS_STAT_CHANNEL(emcFormat, "emcStatus", "keystick", EMC_NMLFILE);
if (! emcStatusBuffer->valid() ||
EMC_STAT_TYPE != emcStatusBuffer->peek())
{
rcs_print_error("emcStatus buffer not available\n");
delete emcStatusBuffer;
emcStatusBuffer = 0;
emcStatus = 0;
retval = -1;
}
else
{
emcStatus = (EMC_STAT *) emcStatusBuffer->get_address();
}
}

return retval;
}

static int emcErrorNmlGet()
{
int retval = 0;

if (emcErrorBuffer == 0)
{
emcErrorBuffer = new NML(nmlErrorFormat, "emcError", "keystick", EMC_NMLFILE);
if (! emcErrorBuffer->valid())
{
rcs_print_error("emcError buffer not available\n");
delete emcErrorBuffer;
emcErrorBuffer = 0;
retval = -1;
}
}

return retval;
}

// string for ini file version num
static char version_string[LINELEN] = "";

// destructively converts string to its uppercase counterpart
static char *upcase(char *string)
{
char *ptr = string;

while (*ptr)
{
*ptr = toupper(*ptr);
ptr++;
}

return string;
}

static int iniLoad(const char *filename)
{
IniFile inifile;
const char *inistring;
char machine[LINELEN] = "";
char version[LINELEN] = "";
char displayString[LINELEN] = "";
int jogPol;

// open it
if (-1 == inifile.Open(filename))
{
return -1;
}

if ((inistring = inifile.Find("MACHINE", "EMC")))
{
strcpy(machine, inistring);

if ((inistring = inifile.Find("VERSION", "EMC")))
{
sscanf(inistring, "$Revision: %s", version);

sprintf(version_string, "%s EMC Version %s", machine, version);
}
}

if ((inistring = inifile.Find("MAX_VELOCITY", "TRAJ")))
{
if (1 != sscanf(inistring, "%lf", &TRAJ_MAX_VELOCITY))
{
TRAJ_MAX_VELOCITY = DEFAULT_TRAJ_MAX_VELOCITY;
}
}
else
{
TRAJ_MAX_VELOCITY = DEFAULT_TRAJ_MAX_VELOCITY;
}

if ((inistring = inifile.Find("PROGRAM_PREFIX", "DISPLAY")))
{
if (1 != sscanf(inistring, "%s", programPrefix))
{
programPrefix[0] = 0;
}
}
else
{
programPrefix[0] = 0;
}

if ((inistring = inifile.Find("POSITION_OFFSET", "DISPLAY")))
{
if (1 == sscanf(inistring, "%s", displayString))
{
upcase(displayString);
if (! strcmp(displayString, "ABSOLUTE"))
{
coords = COORD_ABSOLUTE;
}
else if (! strcmp(displayString, "RELATIVE"))
{
coords = COORD_RELATIVE;
}
else
{
// error-- invalid value
// ignore
}
}
else
{
// error-- no value provided
// ignore
}
}
else
{
// no line at all
// ignore
}

if ((inistring = inifile.Find("POSITION_FEEDBACK", "DISPLAY")))
{
if (1 == sscanf(inistring, "%s", displayString))
{
upcase(displayString);
if (! strcmp(displayString, "ACTUAL"))
{
posDisplay = POS_DISPLAY_ACT;
}
else if (! strcmp(displayString, "COMMANDED"))
{
posDisplay = POS_DISPLAY_CMD;
}
else
{
// error-- invalid value
// ignore
}
}
else
{
// error-- no value provided
// ignore
}
}
else
{
// no line at all
// ignore
}

xJogPol = 1; // set to default
if ((inistring = inifile.Find("JOGGING_POLARITY", "AXIS_0")) &&
1 == sscanf(inistring, "%d", &jogPol) &&
jogPol == 0)
{
// it read as 0, so override default
xJogPol = 0;
}

yJogPol = 1; // set to default
if ((inistring = inifile.Find("JOGGING_POLARITY", "AXIS_1")) &&
1 == sscanf(inistring, "%d", &jogPol) &&
jogPol == 0)
{
// it read as 0, so override default
yJogPol = 0;
}

zJogPol = 1; // set to default
if ((inistring = inifile.Find("JOGGING_POLARITY", "AXIS_2")) &&
1 == sscanf(inistring, "%d", &jogPol) &&
jogPol == 0)
{
// it read as 0, so override default
zJogPol = 0;
}

//надо добавить
aJogPol = 1; // set to default
if ((inistring = inifile.Find("JOGGING_POLARITY", "AXIS_3")) &&
1 == sscanf(inistring, "%d", &jogPol) &&
jogPol == 0)
{
// it read as 0, so override default
aJogPol = 0;
}

// close it
inifile.Close();

return 0;;
}

int tryNml()
{
double end;
int good;
#define RETRY_TIME 10.0 // seconds to wait for subsystems to come up
#define RETRY_INTERVAL 1.0 // seconds between wait tries for a subsystem

if ((EMC_DEBUG & EMC_DEBUG_NML) == 0) {
set_rcs_print_destination(RCS_PRINT_TO_NULL); // inhibit diag
// messages
}
end = RETRY_TIME;
good = 0;
do {
if (0 == emcTaskNmlGet()) {
good = 1;
break;
}
esleep(RETRY_INTERVAL);
end -= RETRY_INTERVAL;
} while (end > 0.0);
if ((EMC_DEBUG & EMC_DEBUG_NML) == 0) {
set_rcs_print_destination(RCS_PRINT_TO_STDOUT); // inhibit diag
// messages
}
if (!good) {
return -1;
}

if ((EMC_DEBUG & EMC_DEBUG_NML) == 0) {
set_rcs_print_destination(RCS_PRINT_TO_NULL); // inhibit diag
// messages
}
end = RETRY_TIME;
good = 0;
do {
if (0 == emcErrorNmlGet()) {
good = 1;
break;
}
esleep(RETRY_INTERVAL);
end -= RETRY_INTERVAL;
} while (end > 0.0);
if ((EMC_DEBUG & EMC_DEBUG_NML) == 0) {
set_rcs_print_destination(RCS_PRINT_TO_STDOUT); // inhibit diag
// messages
}
if (!good) {
return -1;
}

return 0;

#undef RETRY_TIME
#undef RETRY_INTERVAL
}

int main(int argc, char *argv[])
{
int dump = 0;
struct winsize size;
int curx, cury;
int t;
int typing = 0;
#define TYPEBUFFERSIZE ASCLINELEN
char typebuffer[TYPEBUFFERSIZE];
char lastmdi[TYPEBUFFERSIZE] = "";
int typeindex = 0;
enum {IACT_NONE = 1, IACT_OPEN, IACT_MDI, IACT_LOAD_TOOL, IACT_OPEN_LOG,
IACT_END} interactive = IACT_NONE;
//char keystick[] = "keystick";
int charHandled;

// process command line args, indexing argv[] from [1]
for (t = 1; t < argc; t++)
{
// try -dump
if (!strcmp(argv[t], "-dump"))
{
dump = 1;
continue;
}

// try -nml
if (!strcmp(argv[t], "-nml"))
{
if (t == argc - 1) // if last, can't read past it
{
printf("syntax: -nml <nmlfile>\n");
exit(1);
}
else
{
strcpy(EMC_NMLFILE, argv[t+1]);
t++; // step over nmlfile
continue;
}
}

// try -ini
if (!strcmp(argv[t], "-ini"))
{
if (t == argc - 1)
{
printf("syntax: -ini <inifile\n");
exit(1);
}
else
{
strcpy(EMC_INIFILE, argv[t+1]);
t++; // step over inifile
continue;
}
}

// try -noerror
if (!strcmp(argv[t], "-noerror"))
{
catchErrors = 0;
continue;
}

// try -usecs for cycle time in microseconds
if (!strcmp(argv[t], "-usecs"))
{
if (t == argc - 1 ||
1 != sscanf(argv[t + 1], "%d", &usecs) ||
usecs <= 0 ||
usecs >= 1000000)
{
printf("syntax: -usecs <1..999999 microsecond polling period>\n");
exit(1);
}
else
{
t++;
continue;
}
}

// try -dur for delay until repeat
if (!strcmp(argv[t], "-dur"))
{
if (t == argc - 1 ||
1 != sscanf(argv[t + 1], "%d", &FIRST_KEYUP_DELAY) ||
FIRST_KEYUP_DELAY < 0)
{
printf("syntax: -dur <usecs delay until first repeat>\n");
exit(1);
}
else
{
t++;
continue;
}
}

// try -dbr for delay between repeats
if (!strcmp(argv[t], "-dbr"))
{
if (t == argc - 1 ||
1 != sscanf(argv[t + 1], "%d", &NEXT_KEYUP_DELAY) ||
NEXT_KEYUP_DELAY < 0)
{
printf("syntax: -dbr <usecs delay between repeats>\n");
exit(1);
}
else
{
t++;
continue;
}
}

}

// read INI file
iniLoad(EMC_INIFILE);

// trap SIGINT
signal(SIGINT, quit);

#ifdef LOG
errorFp = fopen(ERROR_FILE, "w");
// failure here just disables logging
#endif

// init NML
if (! dump)
{
if(tryNml())
{
exit(1);
}
}

// set up curses
initscr();
cbreak();
noecho();
nonl();
intrflush(stdscr, FALSE);
keypad(stdscr, TRUE);
helpwin = newwin(0, 0, 0, 0);
diagwin = newwin(0, 0, 0, 0);
toolwin = newwin(0, 0, 0, 0);
logwin = newwin(0, 0, 0, 0);
progwin = newwin(0, 0, 0, 0);
window = stdscr;

// fill in strings

for (t = 0; t < ASCLINELEN; t++)
{
line_blank[t] = ' ';
}
line_blank[ASCLINELEN] = 0;

for (t = 0; t < ASCLINELEN; t++)
{
bottom_string[t] = '-';
}
bottom_string[ASCLINELEN] = 0;
t = (ASCLINELEN - strlen(version_string)) / 2;
if (t >= 0)
{
memcpy(&bottom_string[t], version_string, strlen(version_string));
}

// get screen width and height
wbegy = 0;
wbegx = 0;
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &size) < 0)
{
// use 80x24 as default
wmaxy = 23;
wmaxx = 79;
}
else
{
wmaxy = size.ws_row - 1;
wmaxx = size.ws_col - 1;
}

// and set them here
cury = wmaxy;
curx = wbegx;
wmove(window, cury, curx);
wrefresh(window);

// set up interval timer
if (!dump)
{
startTimer(usecs);
}

while (! done)
{
oldch = ch;
int keypress = getch();
if(keypress == ERR)
{
idleHandler();
continue;
}
ch = (chtype) keypress;

// check for ^C that may happen during blocking read
if (done)
{
break;
}

if (dump)
{
mvwaddstr(window, wmaxy, wbegx, line_blank);
sprintf(scratch_string, "%12o", (int) ch);
mvwaddstr(window, wmaxy, wbegx, scratch_string);
wmove(window, wmaxy, wbegx);
wrefresh(window);

if (ch == 'q')
break;
else
continue;
}

if (ch != oldch)
{
keyup_count = FIRST_KEYUP_DELAY;
}
else
{
keyup_count = NEXT_KEYUP_DELAY;
//**************************************************************
// read NML status */
updateStatus();
printStatus();
}

// set up a first switch on ch, for those characters that
// are to be looked at before the interactive typing string.
// set flag signifying the char has been handled, which will
// be reset in the default (not handled) case
charHandled = 1;
switch (ch)
{
/*
To implement a "repeated key," whose actions are done
during the first and every repeated key, do this:

case MY_REPEATED_KEY:
// do action
// you need do nothing else
break;

To implement a "single key," whose actions are done
once and not repeated if the key repeats, do this:

case MY_SINGLE_KEY:
if (oldch != ch)
{
// do action
// you need do nothing else
}
break;

The simulated key-up event and setting of oldch is done
automatically elsewhere.
*/

case ESC: // task abort (abort everything)
task_abort_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(task_abort_msg);
emcCommandWait(emcCommandSerialNumber);
break;

case TAB: // toggle highlight
if (window == diagwin)
{
// toggle dianostics highlight
if (diagtab == DIAG_USECS)
diagtab = DIAG_FIRST_KEYUP_DELAY;
else if (diagtab == DIAG_FIRST_KEYUP_DELAY)
diagtab = DIAG_NEXT_KEYUP_DELAY;
else
diagtab = DIAG_USECS;
}
break;

case ALT('o'): // open log
case ALT('O'):
if (oldch != ch)
{
typing = 1;
typeindex = 0;
interactive = IACT_OPEN_LOG;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "log file to open: ");
wrefresh(window);
critFlag = 0;
}
break;


case CTL('L'): // redraw current window
clearWindow();
printStatus();
break;

case KEY_F(1): // toggle estop
if (oldch != ch)
{
if (emcStatus->task.state == EMC_TASK_STATE_ESTOP)
{
state_msg.state = EMC_TASK_STATE_ESTOP_RESET;
}
else
{
state_msg.state = EMC_TASK_STATE_ESTOP;
}
state_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(state_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case KEY_F(2): // toggle servos
if (oldch != ch)
{
if (emcStatus->task.state == EMC_TASK_STATE_ESTOP_RESET)
{
state_msg.state = EMC_TASK_STATE_ON;
}
else
{
state_msg.state = EMC_TASK_STATE_OFF;
}
state_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(state_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case KEY_F(3): // to into manual mode
if (oldch != ch)
{
mode_msg.mode = EMC_TASK_MODE_MANUAL;
mode_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(mode_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case KEY_F(4): // go into auto mode
if (oldch != ch)
{
mode_msg.mode = EMC_TASK_MODE_AUTO;
mode_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(mode_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case KEY_F(5): // go into mdi mode
if (oldch != ch)
{
mode_msg.mode = EMC_TASK_MODE_MDI;
mode_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(mode_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case KEY_F(6): // reset interpreter
if (oldch != ch)
{
task_plan_init_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(task_plan_init_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case KEY_F(7): // toggle mist
if (oldch != ch)
{
if (emcStatus->io.coolant.mist)
{
emc_coolant_mist_off_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_coolant_mist_off_msg);
emcCommandWait(emcCommandSerialNumber);
}
else
{
emc_coolant_mist_on_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_coolant_mist_on_msg);
emcCommandWait(emcCommandSerialNumber);
}
}
break;

case KEY_F(8): // toggle flood
if (oldch != ch)
{
if (emcStatus->io.coolant.flood)
{
emc_coolant_flood_off_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_coolant_flood_off_msg);
emcCommandWait(emcCommandSerialNumber);
}
else
{
emc_coolant_flood_on_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_coolant_flood_on_msg);
emcCommandWait(emcCommandSerialNumber);
}
}
break;

case KEY_F(9): // toggle spindle forward/off
if (oldch != ch)
{
if (emcStatus->motion.spindle.direction == 0)
{
// it's off, so turn forward
emc_spindle_on_msg.speed = 1;
emc_spindle_on_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_on_msg);
emcCommandWait(emcCommandSerialNumber);
}
else
{
// it's not off, so turn off
emc_spindle_off_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_off_msg);
emcCommandWait(emcCommandSerialNumber);
}
}
break;

case KEY_F(10): // toggle spindle reverse/off
if (oldch != ch)
{
if (emcStatus->motion.spindle.direction == 0)
{
// it's off, so turn reverse
emc_spindle_on_msg.speed = -1;
emc_spindle_on_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_on_msg);
emcCommandWait(emcCommandSerialNumber);
}
else
{
// it's not off, so turn off
emc_spindle_off_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_off_msg);
emcCommandWait(emcCommandSerialNumber);
}
}
break;

case KEY_F(11): // spindle speed decrease
if (oldch != ch)
{
// check for running first
if (emcStatus->motion.spindle.direction == 0)
break;

emc_spindle_decrease_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_decrease_msg);
emcCommandWait(emcCommandSerialNumber);
spindleChanging = 1;
}
break;

case KEY_F(12): // spindle speed increase
if (oldch != ch)
{
// check for running first
if (emcStatus->motion.spindle.direction == 0)
break;

emc_spindle_increase_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_increase_msg);
emcCommandWait(emcCommandSerialNumber);
spindleChanging = 1;
}
break;

case KEY_RIGHT:
if (oldch != ch &&
axisJogging == AXIS_NONE)
{
if (jogMode == JOG_INCREMENTAL)
{
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisIndex(AXIS_X);
if (xJogPol)
emc_axis_incr_jog_msg.vel = jogSpeed / 60.0;
else
emc_axis_incr_jog_msg.vel = - jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
emcCommandWait(emcCommandSerialNumber);
// don't set axisJogging, since key up will abort
}
else
{
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_X);
if (xJogPol)
emc_axis_jog_msg.vel = jogSpeed / 60.0;
else
emc_axis_jog_msg.vel = - jogSpeed / 60.0;
emcCommandBuffer->write(emc_axis_jog_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_X;
}
axisSelected = AXIS_X;
}
break;

case KEY_LEFT:
if (oldch != ch &&
axisJogging == AXIS_NONE)
{
if (jogMode == JOG_INCREMENTAL)
{
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisIndex(AXIS_X);
if (xJogPol)
emc_axis_incr_jog_msg.vel = - jogSpeed / 60.0;
else
emc_axis_incr_jog_msg.vel = jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
emcCommandWait(emcCommandSerialNumber);
// don't set axisJogging, since key up will abort
}
else
{
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_X);
if (xJogPol)
emc_axis_jog_msg.vel = - jogSpeed / 60.0;
else
emc_axis_jog_msg.vel = jogSpeed / 60.0;
emcCommandBuffer->write(emc_axis_jog_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_X;
}
axisSelected = AXIS_X;
}
break;

case KEY_UP:
if (oldch != ch &&
axisJogging == AXIS_NONE)
{
if (jogMode == JOG_INCREMENTAL)
{
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisIndex(AXIS_Y);
if (yJogPol)
emc_axis_incr_jog_msg.vel = jogSpeed / 60.0;
else
emc_axis_incr_jog_msg.vel = - jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
emcCommandWait(emcCommandSerialNumber);
// don't set axisJogging, since key up will abort
}
else
{
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_Y);
if (yJogPol)
emc_axis_jog_msg.vel = jogSpeed / 60.0;
else
emc_axis_jog_msg.vel = - jogSpeed / 60.0;
emcCommandBuffer->write(emc_axis_jog_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_Y;
}
axisSelected = AXIS_Y;
}
break;

case KEY_DOWN:
if (oldch != ch &&
axisJogging == AXIS_NONE)
{
if (jogMode == JOG_INCREMENTAL)
{
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisIndex(AXIS_Y);
if (yJogPol)
emc_axis_incr_jog_msg.vel = - jogSpeed / 60.0;
else
emc_axis_incr_jog_msg.vel = jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
emcCommandWait(emcCommandSerialNumber);
// don't set axisJogging, since key up will abort
}
else
{
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_Y);
if (yJogPol)
emc_axis_jog_msg.vel = - jogSpeed / 60.0;
else
emc_axis_jog_msg.vel = jogSpeed / 60.0;
emcCommandBuffer->write(emc_axis_jog_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_Y;
}
axisSelected = AXIS_Y;
}
break;

case KEY_PPAGE:
if (oldch != ch &&
axisJogging == AXIS_NONE)
{
if (jogMode == JOG_INCREMENTAL)
{
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisIndex(AXIS_Z);
if (zJogPol)
emc_axis_incr_jog_msg.vel = jogSpeed / 60.0;
else
emc_axis_incr_jog_msg.vel = - jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
emcCommandWait(emcCommandSerialNumber);
// don't set axisJogging, since key up will abort
}
else
{
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_Z);
if (zJogPol)
emc_axis_jog_msg.vel = jogSpeed / 60.0;
else
emc_axis_jog_msg.vel = - jogSpeed / 60.0;
emcCommandBuffer->write(emc_axis_jog_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_Z;
}
axisSelected = AXIS_Z;
}
break;

case KEY_NPAGE:
if (oldch != ch &&
axisJogging == AXIS_NONE)
{
if (jogMode == JOG_INCREMENTAL)
{
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisIndex(AXIS_Z);
if (zJogPol)
emc_axis_incr_jog_msg.vel = - jogSpeed / 60.0;
else
emc_axis_incr_jog_msg.vel = jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
emcCommandWait(emcCommandSerialNumber);
// don't set axisJogging, since key up will abort
}
else
{
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_Z);
if (zJogPol)
emc_axis_jog_msg.vel = - jogSpeed / 60.0;
else
emc_axis_jog_msg.vel = jogSpeed / 60.0;
emcCommandBuffer->write(emc_axis_jog_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_Z;
}
axisSelected = AXIS_Z;
}
break;
//и сюда кое чего дописать**********************************************/
case '+':
if (oldch != ch &&
axisJogging == AXIS_NONE)
{
if (jogMode == JOG_INCREMENTAL)
{
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisIndex(AXIS_A);
if (aJogPol)
emc_axis_incr_jog_msg.vel = jogSpeed / 60.0;
else
emc_axis_incr_jog_msg.vel = - jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
emcCommandWait(emcCommandSerialNumber);
// don't set axisJogging, since key up will abort
}
else
{
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_A);
if (aJogPol)
emc_axis_jog_msg.vel = jogSpeed / 60.0;
else
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_A);
if (aJogPol)
emc_axis_jog_msg.vel = jogSpeed / 60.0;
else
emc_axis_jog_msg.vel = - jogSpeed / 60.0;
emcCommandBuffer->write(emc_axis_jog_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_A;
}
axisSelected = AXIS_A;
}
break;

case '-':
if (oldch != ch &&
axisJogging == AXIS_NONE)
{
if (jogMode == JOG_INCREMENTAL)
{
emc_axis_incr_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_incr_jog_msg.axis = axisIndex(AXIS_A);
if (aJogPol)
emc_axis_incr_jog_msg.vel = - jogSpeed / 60.0;
else
emc_axis_incr_jog_msg.vel = jogSpeed / 60.0;
emc_axis_incr_jog_msg.incr = jogIncrement;
emcCommandBuffer->write(emc_axis_incr_jog_msg);
emcCommandWait(emcCommandSerialNumber);
// don't set axisJogging, since key up will abort
}
else
{
jogMode = JOG_CONTINUOUS;
emc_axis_jog_msg.serial_number = ++emcCommandSerialNumber;
emc_axis_jog_msg.axis = axisIndex(AXIS_A);
if (aJogPol)
emc_axis_jog_msg.vel = - jogSpeed / 60.0;
else
emc_axis_jog_msg.vel = jogSpeed / 60.0;
emcCommandBuffer->write(emc_axis_jog_msg);
emcCommandWait(emcCommandSerialNumber);
axisJogging = AXIS_A;
}
axisSelected = AXIS_A;
}
break;

case KEY_HOME: // home selected axis
if (oldch != ch)
{
emc_axis_home_msg.axis = axisIndex(axisSelected);
emc_axis_home_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_axis_home_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case KEY_END: // end this program
if (oldch != ch)
{
typing = 1;
typeindex = 0;
interactive = IACT_END;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "really quit? (y/n): ");
wrefresh(window);
critFlag = 0;
}
break;

default:
charHandled = 0;
break;
} // end of first switch (ch)

// now handle interactive typing, since immediate chars have
// just been handled

if (typing &&
! charHandled)
{
if (ch == RETURN)
{
typing = 0;
typebuffer[typeindex] = 0;
typeindex = 0;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
wmove(window, wmaxy, wbegx);
wrefresh(window);
critFlag = 0;

// now handle typed string
switch (interactive)
{
case IACT_OPEN:
strcpy(task_plan_open_msg.file, typebuffer);
task_plan_open_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(task_plan_open_msg);
emcCommandWait(emcCommandSerialNumber);
strcpy(programFile, task_plan_open_msg.file);
programOpened = 1;
if (programFp)
{
fclose(programFp);
}
programFp = fopen(programFile, "r");
programLineText[0] = 0;
programFpLine = 0;
interactive = IACT_NONE;
break;

case IACT_MDI:
if (typebuffer[0] == 0)
break; // ignore blank lines
strcpy(lastmdi, typebuffer); // save it
strcpy(task_plan_execute_msg.command, typebuffer);
task_plan_execute_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(task_plan_execute_msg);
emcCommandWait(emcCommandSerialNumber);
interactive = IACT_NONE;
break;

case IACT_LOAD_TOOL:
strcpy(emc_tool_load_tool_table_msg.file, typebuffer);
emc_tool_load_tool_table_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_tool_load_tool_table_msg);
emcCommandWait(emcCommandSerialNumber);
interactive = IACT_NONE;
break;

case IACT_END:
if (typebuffer[0] == 'y' ||
typebuffer[0] == 'Y')
{
done = 1;
}

interactive = IACT_NONE;
break;

default: // ignore
break;
}
}
else if (ch == KEY_BACKSPACE || // try all the backspace chars
ch == 8 ||
ch == 127)
{
if (typeindex == 0)
{
// we're at first spot-- ignore
continue;
}
--typeindex;
critFlag = 1;
getyx(window, cury, curx);
--curx;
mvwaddch(window, cury, curx, ' ');
wmove(window, cury, curx);
wrefresh(window);
critFlag = 0;
}
else
{
if (typeindex >= TYPEBUFFERSIZE - 1)
{
// we're at last spot, which we need for null-- ignore
continue;
}
typebuffer[typeindex++] = ch;
critFlag = 1;
waddch(window, ch);
wrefresh(window);
critFlag = 0;
}

// continue with while (! done), so we skip over the normal
// handling of alphanumeric chars
continue;

} // end of if (typing)

// set up a second switch on ch, for those alphanumeric chars that
// can be part of an interactive string
switch (ch)
{
case RETURN:
if (oldch != ch)
{
// clear all error buffers
critFlag = 1;
mvwaddstr(stdscr, ERR_Y, ERR_X, line_blank);
mvwaddstr(helpwin, ERR_Y, ERR_X, line_blank);
mvwaddstr(diagwin, ERR_Y, ERR_X, line_blank);
mvwaddstr(toolwin, ERR_Y, ERR_X, line_blank);
mvwaddstr(logwin, ERR_Y, ERR_X, line_blank);
mvwaddstr(progwin, ERR_Y, ERR_X, line_blank);
wmove(window, wmaxy, wbegx);
wrefresh(window);
critFlag = 0;
}
break;

case '?': // toggle help screen
critFlag = 1;
if (window == stdscr)
{
window = helpwin;
}
else if (window == helpwin)
{
window = toolwin;
}
else if (window == toolwin)
{
window = logwin;
}
else if (window == logwin)
{
window = diagwin;
}
else if (window == diagwin)
{
window = progwin;
}
else if (window == progwin)
{
window = stdscr;
}
else
{
window = stdscr;
}
critFlag = 0;
clearWindow();
printStatus();
break;

case '#': // toggle abs/rel mode
if (oldch != ch)
{
switch (coords)
{
case COORD_RELATIVE:
coords = COORD_ABSOLUTE;
break;
case COORD_ABSOLUTE:
coords = COORD_RELATIVE;
break;
default:
coords = COORD_RELATIVE;
break;
}
}
break;

case '@': // toggle cmd/act mode
if (oldch != ch)
{
switch (posDisplay)
{
case POS_DISPLAY_ACT:
posDisplay = POS_DISPLAY_CMD;
break;
case POS_DISPLAY_CMD:
posDisplay = POS_DISPLAY_ACT;
break;
default:
posDisplay = POS_DISPLAY_ACT;
break;
}
}
break;

case 'x':
case 'X':
if (oldch != ch)
{
if (emcStatus->task.mode == EMC_TASK_MODE_MDI)
{
typing = 1;
typeindex = 1;
typebuffer[0] = ch;
typebuffer[1] = 0;
interactive = IACT_MDI;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "mdi command: ");
waddch(window, ch);
wrefresh(window);
critFlag = 0;
}
else
{
axisSelected = AXIS_X;
}
}
break;

case 'y':
case 'Y':
if (oldch != ch)
{
if (emcStatus->task.mode == EMC_TASK_MODE_MDI)
{
typing = 1;
typeindex = 1;
typebuffer[0] = ch;
typebuffer[1] = 0;
interactive = IACT_MDI;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "mdi command: ");
waddch(window, ch);
wrefresh(window);
critFlag = 0;
}
else
{
axisSelected = AXIS_Y;
}
}
break;

case 'z':
case 'Z':
if (oldch != ch)
{
if (emcStatus->task.mode == EMC_TASK_MODE_MDI)
{
typing = 1;
typeindex = 1;
typebuffer[0] = ch;
typebuffer[1] = 0;
interactive = IACT_MDI;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "mdi command: ");
waddch(window, ch);
wrefresh(window);
critFlag = 0;
}
else
{
axisSelected = AXIS_Z;
}
}
break;
/* сюда дописать про А*/
case 'a':
case 'A':
if (oldch != ch)
{
if (emcStatus->task.mode == EMC_TASK_MODE_MDI)
{
typing = 1;
typeindex = 1;
typebuffer[0] = ch;
typebuffer[1] = 0;
interactive = IACT_MDI;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "mdi command: ");
waddch(window, ch);
wrefresh(window);
critFlag = 0;
}
else
{
axisSelected = AXIS_A;
}
}
break;

case 'i': // incremental jog toggle
case 'I':
if (jogMode == JOG_INCREMENTAL)
{
jogIncrement *= 10.0;
if (jogIncrement >= 0.9)
{
jogIncrement = 0.0001;
}
}
jogMode = JOG_INCREMENTAL;
break;

case 'c': // continuous jog
case 'C':
if (oldch != ch)
{
jogMode = JOG_CONTINUOUS;
}
break;

case '<':
case ',':
if (window == diagwin)
{
if (diagtab == DIAG_USECS)
{
usecs -= 10000;
if (usecs < 10000)
usecs = 10000;

startTimer(usecs);
}
else if (diagtab == DIAG_FIRST_KEYUP_DELAY)
{
FIRST_KEYUP_DELAY -= 10000;
if (FIRST_KEYUP_DELAY <= 0)
FIRST_KEYUP_DELAY = 0;
}
else
{
NEXT_KEYUP_DELAY -= 10000;
if (NEXT_KEYUP_DELAY <= 0)
NEXT_KEYUP_DELAY = 0;
}
}
else
{
jogSpeed -= 1;
if (jogSpeed < 1)
jogSpeed = 1;
}
break;

case '>':
case '.':
if (window == diagwin)
{
if (diagtab == DIAG_USECS)
{
usecs += 10000;
if (usecs > 900000)
usecs = 900000;

startTimer(usecs);
}
else if (diagtab == DIAG_FIRST_KEYUP_DELAY)
{
FIRST_KEYUP_DELAY += 10000;
}
else
{
NEXT_KEYUP_DELAY += 10000;
}
}
else
{
jogSpeed += 1;
if (jogSpeed > TRAJ_MAX_VELOCITY * 60.0)
{
jogSpeed = TRAJ_MAX_VELOCITY * 60.0;
}
}
break;
//надо по другому распределить скорости до 150%
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
// feed override
if (oldch != ch)
{
if (ch == '0')
{
emc_traj_set_scale_msg.scale = 1.0;
}
else
{
emc_traj_set_scale_msg.scale = double (ch - '1' + 1) / 10.0;
}
emc_traj_set_scale_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_traj_set_scale_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case 'b': // spindle brake off
if (oldch != ch)
{
emc_spindle_brake_release_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_brake_release_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case 'B': // spindle brake on
if (oldch != ch)
{
emc_spindle_brake_engage_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_spindle_brake_engage_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case 'o':
case 'O':
if (oldch != ch)
{
if (emcStatus->task.mode != EMC_TASK_MODE_AUTO)
break;

typing = 1;
strcpy(typebuffer, programPrefix);
typeindex = strlen(programPrefix);
interactive = IACT_OPEN;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "program to open: ");
waddstr(window, typebuffer);
wrefresh(window);
critFlag = 0;
}
break;

case 'r':
case 'R':
if (oldch != ch)
{
if (emcStatus->task.mode != EMC_TASK_MODE_AUTO)
break;

if (! programOpened)
{
// send a request to open the last one
strcpy(task_plan_open_msg.file, programFile);
task_plan_open_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(task_plan_open_msg);
emcCommandWait(emcCommandSerialNumber);
}
task_plan_run_msg.serial_number = ++emcCommandSerialNumber;
task_plan_run_msg.line = 0;
emcCommandBuffer->write(task_plan_run_msg);
emcCommandWait(emcCommandSerialNumber);
programOpened = 0;
}
break;

case 'p':
case 'P':
if (oldch != ch)
{
task_plan_pause_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(task_plan_pause_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case 's':
case 'S':
if (oldch != ch)
{
task_plan_resume_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(task_plan_resume_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;
/* И что удивительно в хелпе про это по другому
надо по другому переделать потому, что перекекаются хоткеи */
// case 'a':
// case 'A':
case 'f':
case 'F':

if (oldch != ch)
{
task_plan_step_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(task_plan_step_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case 'u':
if (oldch != ch)
{
emc_lube_off_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_lube_off_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case 'U':
if (oldch != ch)
{
emc_lube_on_msg.serial_number = ++emcCommandSerialNumber;
emcCommandBuffer->write(emc_lube_on_msg);
emcCommandWait(emcCommandSerialNumber);
}
break;

case '\'':
case '\"':
if (oldch != ch)
{
if (emcStatus->task.mode != EMC_TASK_MODE_MDI)
break;

typing = 1;
interactive = IACT_MDI;

// stuff last command
strcpy(typebuffer, lastmdi);
typeindex = strlen(typebuffer);

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "mdi command: ");
waddstr(window, typebuffer);
wrefresh(window);
critFlag = 0;
}
break;

case 'm':
case 'M':
case 'g':
case 'G':
if (oldch != ch)
{
if (emcStatus->task.mode != EMC_TASK_MODE_MDI)
break;

typing = 1;
typeindex = 1;
typebuffer[0] = ch;
typebuffer[1] = 0;
interactive = IACT_MDI;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "mdi command: ");
waddch(window, ch);
wrefresh(window);
critFlag = 0;
}
break;

case 'l':
case 'L':
if (oldch != ch)
{
typing = 1;
typeindex = 0;
interactive = IACT_LOAD_TOOL;

critFlag = 1;
mvwaddstr(window, wmaxy, wbegx, line_blank);
mvwaddstr(window, wmaxy, wbegx, "tool file to load: ");
wrefresh(window);
critFlag = 0;
}
break;

default:
break;
} // end of second switch (ch)

} // end of while (! done)

// call ^C signal handler directly to terminate cleanly
quit(0);

return 0;
}
Вложения
new_keystick.rar
(13.65 КБ) 189 скачиваний
Ответить

Вернуться в «LinuxCNC»