PDA

Просмотр полной версии : прерывания и оформление - где-то накосячил.


sheppard
18.08.2020, 11:11
Железяка ругается.

https://yadi.sk/i/pzrEBD-HLKBXzQ

https://yadi.sk/i/ei_YXWvuNzXTuw

Вот зуб даю что где-то мелкопакостную мелочь пропустил...

Роботёр
18.08.2020, 11:49
синтаксис прерывания неверный.
interrupt decl=32 when $meas_pulse[3]==true then do forward() - неправильно
interrupt decl 32 when $meas_pulse[3]==true do forward() - правильно

sheppard
18.08.2020, 13:22
Это уже злит.

Ругается, что после INI должна быть '('

Вот кто придумывал синтаксис :)))

Все перепробовал - или не работает
interrupt decl 32 when $meas_pulse[3]==true do forward()

или не инициализируются переменные.

В описанке КРЛ нет даже намека как оформить INI :)

Где я снова накосячил?

sheppard
18.08.2020, 13:30
https://yadi.sk/i/kwHV4iaFW3MZWw

https://yadi.sk/i/rIDIJ_L4Ime5Qg

Не бывает же такого... наверняка все же есть кривые правила KRL

Роботёр
18.08.2020, 13:43
что вообще у тебя за строчка ini? ты руками ее написал или это формуляр, который создается вместе с модулем?
лучше скинь архив

sheppard
18.08.2020, 13:54
все руками пишу :) надо же разобраться...

строчу в оранжэдите

как оформляется Ini, причем без подпрограмм и хитростей? все объявляемые переменные просто перечисляются.

ну не может же там быть подводных камней :)

Роботёр
18.08.2020, 14:38
я не понимаю. ini - это формуляр, который создается при создании модуля. Он не обязателен. Если у тебя это просто текстовая строчка, то конечно робот ее не поймет. Пришли архив.
Вот так вот выглядит полностью открытый ini формуляр
;FOLD INI
;FOLD BASISTECH INI
GLOBAL INTERRUPT DECL 3 WHEN $STOPMESS==TRUE DO IR_STOPM ( )
INTERRUPT ON 3
BAS (#INITMOV,0 )
;ENDFOLD (BASISTECH INI)
;FOLD USER INI
;Make your modifications here

;ENDFOLD (USER INI)
;ENDFOLD (INI)

sheppard
18.08.2020, 15:04
примерно так и понял, но все весело.

Ini, по сути, это то, что интерпретатор проглядывает, но не использует.

Bas (#initmov,0 ) - но вот это что за чудо? у меня же потом есть инициализация координат.

где-то есть хитрость.

---

Код скину, но там ничего интересного :) Поэтому и хочу разобраться.

sheppard
26.08.2020, 11:35
Странно - все делаю в OrangeEdit'е...

кажется, подглюкивает? Ведь файлы, которые он "ест", обычные текстовые.

То есть видятся вот так - https://yadi.sk/d/wlbzBvmLDz89uQ - в архиве все как есть, ровно то, что прекрасно глотает OrangeEdit, и в нем же файлы создавались. Это все ошибочные, но стали они такими только после добавления:
global interrupt decl 32 when $meas_pulse[3]==true do forward()


Первые 2-3-4 файла показывают смысловые ошибки "требуется операнд" на строке global interrupt decl 32 when $meas_pulse[3]==true do forward()

не слишком ясно, что хочет, но хоть понятно.

Но вот в последних трех файлах полный зашквар. Требует после INI скобку "(". Может надо было и закрыть? Но уже люто ругается даже сам Orange. На всякий пожарный потасовал строки, но там уже ругань что переменные объявляются не в INI.

===

может влепить напрямую в Оранже

GLOBAL INTERRUPT DECL 3 WHEN $STOPMESS==TRUE DO IR_STOPM ( )
INTERRUPT ON 3
BAS (#INITMOV,0 )

?

Но матерится. Другое дело что, мол, пусть Оранж матерится, но робот делает... ?;)

Роботёр
26.08.2020, 12:08
я не вижу ни одной программы, в которой бы ты объявил прерывание. где смотреть?

sheppard
26.08.2020, 12:25
DEF interrupt_20( )

GLOBAL INTERRUPT DECL 33 WHEN $MEAS_PULSE[3]==TRUE DO forward()

INI

INT i;
INT t;
INT l;
INT cou;
INT hicou;
INT cmhicou;
INT r;

и т.д.

Ну дословный же перевод - глобальное объявление прерывания 33, когда $MEAS и далее...

Я же просто по форуму нашел обсуждение ошибочного, и быстро исправленного примера: http://robotforum.ru/forum/showthread.php?t=4996&highlight=interrupt

====

Вот потому и упираюсь рогом не в логику или даже семантику, а в, видимо, оформление.

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

Значит что-то не так с оформлением... Но что? В сотенностраничных талмудах уже упрел ковыряться :)))

sheppard
26.08.2020, 13:25
Полнейший маразм... Наплевал на ОранжЭдит и влепил в обычном текстовике. Кстати Оранж весело чавкнул и проглотил, но где делать грамотно INI я так и не нашел.

Однако на оба этих варианта - https://yadi.sk/i/IQlnt-pYIACgXg

выдаётся одинаковая ошибка?!?:
"
Описание не находится а разделе описаний
***INT i;
"

Опупенительно. А где этот раздел тогда, куда пихать свои переменные, если подфолдер fold user ini не подходит, а после всего ini место тоже неподходящее, хотя до возни с прерыванием я тупо строчил
"
INI
INT i;
"
и все прекрасно работало?!!!

Прямо такой же бред, как с костылявым gw-basic на первых PC после нормальных бейсиков для z80, atari и даже бк0010...

Где глюк? :(((

Роботёр
26.08.2020, 14:57
сделай декларацию переменных до формуляра ini

sheppard
26.08.2020, 15:03
гм... сейчас попробую через 10 мин!

sheppard
26.08.2020, 15:35
обалденительно! робот сожрал код.

спасибо!!!

все же это не я тупой, это немцы наперекор своей немецкости оставили сырость в языке! хоть бы взяли за образец простенький, но за полвека буквально вылизанный до блеска синтаксис паскаля.

теперь можно разбираться с самим прерыванием, потому что пока не срабатывает эвент...

Роботёр
26.08.2020, 18:15
еще все переменные можно деккларировать в файле config.dat. при этом они автоматически становятся глобальными.
что с прерыванием, что не срабатывает?

sheppard
28.08.2020, 08:58
само прерывание уже сработало, но нельзя сделать, например, в общем коде
--
PTP_REL{Z 1000}
--

А в процедуре прерывания
--
PTP_REL {Z 100}
--

И вернуться так, чтобы PTP_REL{Z 1000} осталось актуальным, то есть чтобы конечная точка движения не изменилась - робот просто ыдает вполне ожидаемую ошибку и стопорится. Вместо 1000 нужна переменная, но, во-первых, мнений прорва, а в доступных описаниях есть только синтаксис оформления, но рабочих примеров у меня нет.

Пока реалистичными выглядят варианты просто с переменными, как вы указали, но не знаю банально как их там оформлять - это юниты, списки или составные переменные :) просто синтаксис неясен.

Но есть еще, как бает интернет, переменные, которые являются системными, и одна из них, например, в любой момент времени выдает текущее состояние координат. Логично в начале самой процедуры прерывания сохранить в отдельную переменную текущие координаты и конце процедуры отправить PTP_ по этой переменной.

Но снова как с этим работать, чтобы PTP принял переменную. Видимо оба вопроса актуальны: как оформляются все эти e6pos и т.д., в чем их отличие, и как использовать технопеременные с актуальными координатами.

По сути это и есть "окончательное решение робото-вопроса" :)))

P.S.

У меня PTP_REL на больших расстояниях делает заметную дугу (что логично для суставного робота), а чем заменить команду, чтобы движение было строго по прямой?

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

sheppard
28.08.2020, 13:29
с птп разобрался :))) а вот с переменной пока нет.. интернет как у глухонемого в подлодке :)

Ignis
28.08.2020, 19:34
DECL E6POS MyPoint ;объявляем переменную



E6POS MyPoint={X 0,Y 0,Z 0,A 0,B 0,C 0,S 0,T 0,E1 0.0,E2 0.0,E3 0.0,E4 0.0,E5 0.0,E6 0.0} ;Можешь объявить переменную в dat файле с таким же именем что и src, тогда все значения переменной буду перезаписываться в файл

XP1=$POS_ACT ; в твоем прерывании записываем координату события

$VEL_AXIS[1] = 40 ; задаем если надо другую скорость
$ACC_AXIS[1] = 40 ; и ускорение c A1
.
. ; А2-А5
.
$VEL_AXIS[6] = 40 ; скорость
$ACC_AXIS[6] = 40 ; ускорение по A6

Можно не задавать явно значения скорости, тогда эти величины будут взяты из предыдущего PTP, сделанного через тачап

PTP MyPoint ; выполняем движение

sheppard
29.08.2020, 14:13
не понял от слова совсем :)))

---
Тут все ясно:

DECL E6POS MyPoint ;объявляем переменную
E6POS MyPoint={X 0,Y 0,Z 0,A 0,B 0,C 0,S 0,T 0,E1 0.0,E2 0.0,E3 0.0,E4 0.0,E5 0.0,E6 0.0}

XYZ - просто координаты от BASE? (мм, полагаю)
ABC - ?
ST - ?
E1..E6 - углы движков в градусах? И если "да", то дробные значения можно использовать?

Теперь к "боевой" практивке: как мне, например, использовать MyPoint в вычислениях? Мне, например, нужно менять только координату Х.

Я должен по синтаксису написать MyPoint.X=MyPoint.X+10, к примеру? Или MyPoint(X)=MyPoint(X)+10 или использовать {}? В этом вопрос :)))

Суть енамов едина со времен макросов ассемблера :))) Просто немцам в KRL орднунг отшибло наглухо - косяков в банальном оформлении просто больше, чем в первом Питоне :) Разок сделали и не стали что-то вылизывать, мол, инженер за пару дней запомнит :)

2. В вашем примере:
XP1=$POS_ACT

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

Если на все вопросы "да", тогда все совершенно понятно :) Вот только все-таки хотелось бы расшифровку ABCST...

ProductManager
29.08.2020, 18:07
доброго времени суток.

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

Ignis
29.08.2020, 19:00
не понял от слова совсем :)))

---
Тут все ясно:

DECL E6POS MyPoint ;объявляем переменную
E6POS MyPoint={X 0,Y 0,Z 0,A 0,B 0,C 0,S 0,T 0,E1 0.0,E2 0.0,E3 0.0,E4 0.0,E5 0.0,E6 0.0}

...

Если на все вопросы "да", тогда все совершенно понятно :) Вот только все-таки хотелось бы расшифровку ABCST...


Виноват, мой косяк, XP1 надобно заменить на MyPoint

MyPoint.X=MyPoint.X+10 используя оператор выборки "." Как обращение к полю или методу экземпляра класса.

XYZ - координаты точки, но этого мало, так как в этой точке TCP (tool center point) может находиться в бесконечном многообразии вариантов.
Дополнительно используют углы вращения ABC которые однозначно определяют в пространстве положение самого инструмента. Ну вроде как недовектор у него есть конец координат и направление, но нет координат начала.

Е1 - Е6 это положение внешних осей, в данном случае они отсутствуют поэтому можно на них немножко подзабить.

$POS_ACT системное автоотслеживание текущих координат? Не вдаваясь в подробности, что-то вроде того.

sheppard
29.08.2020, 22:53
Отлично :)))

А вот пространственное положение tool'а меня не интересует. Наоборот, мне нужно, чтобы оно оставалось неизменным.

То есть, по идее я могу просто не трогать их, а использовать исключительно MyPoint.X..Z.

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

https://www.facebook.com/henry.sheppard.33/videos/3473295332708628

sheppard
31.08.2020, 09:04
Не вытанцовывается каменный гладиолус!

Суть проста: башка робота двигается по главной траектории. На ней два датчика. Прерывание 5 вызывается при срабатывании первого и пусть просто робот запоминает в currentXYZ текущее значение $POS_ACT. И начинает двигаться по мелкой доп.траектории. Предварительно активируется прерывание 4 (когда срабатывает второй датчик), которое просто должно "наплевать" на выполнение текущей доп.траектории и вернуть голову в currentXYZ, выйти из прерывания 4 и затем сразу же из 5 и продолжить главную траекторию.

Но я даже не могу запомнить currentXYZ = $POS_ACT - ошибка. Вроде "нельзя сохранять в главной программе данные, связанные со временем исполнения".

Вот грубо навскидку - выкинул все, что не относится к проблеме.

===
&ACCESS RV
DEF b01( )

E6POS currentXYZ;

;FOLD INI
;FOLD BASISTECH INI
GLOBAL INTERRUPT DECL 5 WHEN $MEAS_PULSE[3]==TRUE DO found()
INTERRUPT ON 5
GLOBAL INTERRUPT DECL 4 WHEN $MEAS_PULSE[1]==TRUE DO stop_heat()
INTERRUPT ON 4
BAS ( #INITMOV,0 )
;ENDFOLD (BASISTECH INI)
;FOLD USER INI
;ENDFOLD (USER INI)
;ENDFOLD (INI)

$BASE = $NULLFRAME;
$TOOL = $NULLFRAME;
$IPO_MODE = #BASE;

$OV_PRO=100

LOOP

PTP {A1 0, A2 -90, A3 90, A4 90, A5 0, A6 0}

LIN_REL {Z -2000}; main trajectory
LIN_REL {Z 2000}

ENDLOOP

END

def found()
BRAKE F
$OV_PRO=100
INTERRUPT OFF 5 ; founded - 1st trigger is ON
INTERRUPT ON 4 ; closeup check on - activate INT for 2nd trigger
currentXYZ = $POS_ACT
PTP_REL {X 200}; added trajectory
INTERRUPT OFF 4
INTERRUPT ON 5
$OV_PRO=80
end


def stop_heat()
BRAKE F
PTP currentXYZ
end
===

Pavel_T
02.09.2020, 13:31
Привет !
Тут есть пара вещей:
1. Декларация для: E6POS currentXYZ
выбрана неверно. В данном случае, как локальная переменная в
процедуре DEF b01( ), а используется в процедуре прерывания
def found(). Для правильной работы, переменную currentXYZ,
надо объявить или в файле b01.dat, или в файле $config.dat
(т.е глобально). Так же нужно ее проинициализировать до входа в
главный цикл, например currentXYZ = $NULLFRAME

2. Теперь сами прерывания. Тут мне с логикой не все понятно.
Робот двигается вверх вниз. Срабатывает первым прерывание 5. Робот
двигается вперед на 200 мм. и все. Если второе прирывание, которое его теоритически
должно вернуть на первоначальную траекторию, например запаздывает или не походит,
то робот зависает после команды PTP_REL {X 200}.
Мне кажется, что правильно было бы после команды PTP_REL {X 200} сразу дабавить
команду возврата на первоначальную траекторию PTP $POS_RET, а от прерывания 4 отказаться.
Т.е.
def found()
BRAKE F
$OV_PRO=100
INTERRUPT OFF 5 ; founded - 1st trigger is ON
INTERRUPT ON 4 ; closeup check on - activate INT for 2nd trigger
currentXYZ = $POS_ACT
PTP_REL {X 200}; added trajectory
PTP $POS_RET
INTERRUPT OFF 4
INTERRUPT ON 5
$OV_PRO=80
end

sheppard
03.09.2020, 06:05
Ага...

С первым пунктом разобрался :)) просто я по древней ассемблерной привычке все кодирую прямо в ноутпаде, поэтому бывают старые замашки в программировании резидентных программ ;) эдакий перехват 5го, 9го и особенно 13h прерываний под ДОС ;)

А вот логика второго пункта...

Суть в том, чтобы голова робота ехала вперёд, но не дальше 200мм. Но если срабатывает второй датчик, то нужно чтобы голова немедленно вернулась - то есть я вторым датчиком ищу поверхность. Если нахожу, то возвращаюсь на столько мм, сколько успел проехать вперёд по этому 200отмиллиметровому пути. Иначе я башкой робота просто протараню эту поверхность.

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

Вот такие пирожки с котятами... ;)))

sheppard
03.09.2020, 06:26
и ещё момент. в чем разница между $pos_act и $pos_int? а то тут пока рыгорыч глушит Dns и погуглить толком не удается :))) а тут как раз, насколько смутно помню, именно тот случай.

Pavel_T
03.09.2020, 06:57
Тогда попробуй так:
def found()
BRAKE F
$OV_PRO=100
INTERRUPT OFF 5 ; founded - 1st trigger is ON
currentXYZ = $POS_RET
INTERRUPT ON 4 ; closeup check on - activate INT for 2nd trigger
PTP_REL {X 200}; added trajectory
INTERRUPT OFF 4
PTP $POS_RET
INTERRUPT ON 5
$OV_PRO=80
end

Про системные переменные реалтайма есть инфа во всех мануалах по прерываниям и
описания системных переменных (с картинками, там все видно).

ProductManager
03.09.2020, 07:08
и ещё момент. в чем разница между и ? а то тут пока рыгорыч глушит Dns и погуглить толком не удается :))) а тут как раз, насколько смутно помню, именно тот случай.
$pos_act - текущая позиция, в любом месте программы можно вставить. С момента прерывания до считывания этой переменной робот может проехать по инерции некоторое расстояние. См. рис.
$pos_int - позиция в момент прерывания.

sheppard
03.09.2020, 07:26
ага! как и догадывался... спасибище :)))

Pavel_T
03.09.2020, 07:34
Я ошибся, вот так думаю с двумя прерываниями будет правильно:
def found()
BRAKE F
$OV_PRO=100
INTERRUPT OFF 5 ; founded - 1st trigger is ON
currentXYZ = $POS_RET
INTERRUPT ON 4 ; closeup check on - activate INT for 2nd trigger
PTP_REL {X 200}; added trajectory
INTERRUPT OFF 4
PTP currentXYZ
INTERRUPT ON 5
$OV_PRO=80
end

sheppard
03.09.2020, 07:55
У меня ведь как раз так и было изначально, только я запоминал координаты по собственному почину, а не использовал $pos_ret.

Есть хитрости в pos_ret? Ведь если есть то, что подозреваю, то мне и не нужна глоб.переменная. сразу ptp $pos_ret...

И тогда это вложенная переменная. То есть для 4го прерывания она одна, а для 5го другая? Или фокусы и риск тут неуместны?

Pavel_T
03.09.2020, 08:18
Думаю, что $pos_ret это глобальная переменная, которую модифицирует каждое прерывание, но можно посмотреть на пульте в разделе:
Display>View>Single Variable>$pos_ret

sheppard
03.09.2020, 08:25
попробую... через час повеселюсь ;)

sheppard
03.09.2020, 13:30
шевелилка вроде зашевелилась, но есть странности. все-таки Krl - явно сырая недоделка - я, как придурок, который когда-то операционки писал, заявляю со сей безответственностью :)))

проблема возникает при возврате из 200мм-траектории. пока не очень понятно :)))

завтра и на выходных урву по 12 часов.

Pavel_T
03.09.2020, 13:59
Попробуй поменять:
def stop_heat()
BRAKE F
PTP currentXYZ
end

на:
def stop_heat()
BRAKE F
end

sheppard
04.09.2020, 13:27
гм... выглядит логично только если возврат срабатывает, так как координаты ухода с пути запоминаются в некоем подобии стэка.

Суть в том, что у меня по сути получается прерывание в прерывании. Если для запоминания координат есть только одна системная переменная, то 4ое прерывание "затрет" напоминалку от 5го.

И еще дополнительный вопрос: После 5го прерывания мне нужно сдвинуться вдоль главного вертикального пути на 100мм с дезактивированным прерыванием. То есть придется вбить команду PTP (Z 100) в процедуре прерывания (find). Но тогда после возврата тоже получится глупость - робот запутается и застопорится, или на самом деле он будет руководствоваться конечной координатой без оглядки на то, что был "насильственный" сдвиг внутри прерывания?

Pavel_T
06.09.2020, 13:06
Попробовал реализовать прерывание в прерывании. 5-е срабатывает нормально, робот идет вперед
возвращается и продолжает главный путь. Если активировать 4-е прерывание, когда робот начал движение
вперед, то робот не останавливается. Завершает движение вперед и только после этого срабатывает 4-е
прерывание, когда уже не нужно. Пробовал объявлять 4-е прерывание в процедуре found(), выносить движение
вперед в отдельную процедуру, все равно не останавливается. Получается, вызов прерывания из прерывания
не реентерабельный. Единственное, что следует заметить, я тестировал прерывания в режиме Т1. В автомате
картина может быть другая и все работает. У меня просто нет возможности проверить.

sheppard
06.09.2020, 16:24
вот и я борцуюсь :) И тоже пока "никак" от слова "совсем" :)

Но хотя бы решить проблему сдвига - то есть когда я ушел на 5ое прерывание, отработал его, возвращаюсь в исходную точку активации прерывания, но сдвинуться по Z на фикс.расстояние, после чего доехать до конца основного движения.

1. То есть во время доп.сдвига по X прерывание не должно срабатывать. То есть PTP (z) надо использовать внутри прерывания. Однако как себя поведет робот? Мне нужно чтобы он доделал движение как надо и именно в конечную точку. При этом прерывание потом может сработать еще раз (но это как раз нормально).

Pavel_T
07.09.2020, 08:23
Я тут посидел немного и написал небольшой пример программы движения робота с двумя прерываниями,
которые меняют начальную траекторию и возвращаются обратно. Единственный дисклеймер, это то что
сейчас нет возможности закинуть этот пример в живой робот и проверить хотя бы ошибки синтаксиса.
Поэтому будут мысли вслух.

Первое, надо глобально (в файле TestIRQ.dat или $config.dat) объявить перичесление статусов состояния главной
программы робота и основных переменных.
ENUM PROC_STATUS MAIN_UP, MAIN_DOWN, FORWARD200, UP100, RET_FORWARD200, RET_UP100
DECL E6POS UpperPos, LowerPos ;точки главной траектории
DECL PROC_STATUS ACT_STATUS, PRV_STATUS ;задаем переменные для хранения текущего и предыдущего статусов
DECL E6POS RetFw200, RetUp100 ;точки возврата из прерывания на главную траекторию

Робот может находится только по одному из этих логических статусов в процессе работы.
Вначале мы задаем первый статус и входим в главный цикл.
Главный цикл представлят из себя что-то вроде статус менеджера.
Все требуемые движения робота обединены в минимальные логические процедуры.
Эти процедуры между собой не имеют никакого приоритета и выполняются менеджером в
зависимости от текущего статуса.
Каждая такая процедура, после выполнения движения или других логических действий меняет текуций
статус (иногда предварительно запоминая его что-бы потом можно было вернуться) на подходящий по смыслу и
сразу выходит в главный цикл.
Главный цикл, на следующей итерации приступает к обработке нового статуса.
Обработчики прерываний не содержат никаких движений, а выполняют только логические действия
(остановку, запоминание точки возврата, изменение текущего статуса и главное выход из
процедуры движения, где произошло прерывание, в главный цикл по команде RETURN).
Обслуживание движений по статусам установленным в подпрограмме прерывания разделено на две части:
выполнение самого движения и возврат из него.

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

DEF TestIRQ ( )
E6AXIS HOME
DECL INT sts

;FOLD INI;%{PE}
;FOLD BASISTECH INI
GLOBAL INTERRUPT DECL 3 WHEN $STOPMESS==TRUE DO IR_STOPM ( )
INTERRUPT ON 3
BAS (#INITMOV,0 )
;ENDFOLD (BASISTECH INI)
;FOLD USER INI
;Make your modifications here

;ENDFOLD (USER INI)
;ENDFOLD (INI)

;задаем прерывания
INTERRUPT DECL 5 WHEN $MEAS_PULSE[3]==TRUE DO IR_Forward200()
INTERRUPT DECL 4 WHEN $MEAS_PULSE[1]==TRUE DO IR_Up100()

sts = 0
RetFw200 = $NULLFRAME
RetUp100 = $NULLFRAME

HOME = {A1 0, A2 -90, A3 90, A4 90, A5 0, A6 0}

;конвертируем HOME axis pos. в координаты верхней точки
UpperPos = FORWARD(HOME, sts)

;задаем нижнюю точку
LowerPos = UpperPos
LowerPos.Z = LowerPos.Z - 2000

;начальный статус движения (предполагаем, что робот вверху)
ACT_STATUS = #MAIN_DOWN
PRV_STATUS = ACT_STATUS
INTERRUPT ON 5

LOOP
;статус менеджер
SWITCH ACT_STATUS
CASE #MAIN_DOWN
MainMoveDown() ;едем вниз и ждем срабатывания 5 прерывания
CASE #MAIN_UP
MainMoveUp() ;едем вверх и ждем срабатывания 5 прерывания
CASE #FORWARD200
Forward200() ;5 прерывание сработало, едем вперед и ждем срабатывания 4 прерывания
CASE #RET_FORWARD200
RetForward200() ;выходим на главную траекторию после движения вперед
CASE #UP100
Up100() ;4 прерывание сработало, движениу вперед остановлено, едем вверх
CASE #RRET_UP100
RetUp100() ;возвращаемся вниз к точке срабатывания 4 прерывания
ENDSWITCH

WAIT FOR TRUE
ENDLOOP

END

;вниз по главной траектории
DEF MainMoveDown()
LIN LowerPos
ACT_STATUS = #MAIN_UP
END

;вверх по главной траектории
DEF MainMoveUp()
LIN UpperPos
ACT_STATUS = #MAIN_DOWN
END

;обработчик 5 прерывания
DEF IR_Forward200()
BRAKE F
$OV_PRO=100
INTERRUPT OFF 5
INTERRUPT ON 4
RetFw200 = $POS_RET
PRV_STATUS = ACT_STATUS
ACT_STATUS = #FORWARD200
RETURN
END

;обработчик 4 прерывания
DEF IR_Up100()
BRAKE F
RetUp100 = $POS_RET
ACT_STATUS = #UP100
RETURN
END

;просто вперед на 200 мм
DEF Forward200()
PTP_REL {X 200}
ACT_STATUS = #RET_FORWARD200
END

;назад к точке возврата из 5 прерывания
DEF RetForward200()
PTP RetFw200
INTERRUPT OFF 4
INTERRUPT ON 5
$OV_PRO=80
ACT_STATUS = PRV_STATUS ;продолжить прерванное движение: или вверх или вниз
END

;просто вверх на 100 мм
DEF Up100()
LIN_REL {Z 100}
ACT_STATUS = #RET_UP100
END

;назад к точке возврата из 4 прерывания
DEF RetUp100()
PTP RetUp100
ACT_STATUS = #RET_FORWARD200
END

Pavel_T
09.09.2020, 07:23
Наконец то вчера удалось запустить пример на живом роботе. Как и ожидалось, выявилось несколько
досадных багов:
1. Ошибки синтаксиса
CASE #RRET_UP100
вместо
CASE #RET_UP100
2. Думал одно, а написал другое. Обработчики прерывания должны заканчиваться
оператором RESUME, а не RETURN.
3. Перед входом в главный цикл обязательно сбросить счетчик прекомпилятора комманд в 0, иначе
статусы работаю не верно:
$ADVANCE = 0
4. Движения с PTP поменял на LIN для лучшей наглядности.

Вот исправленный пример:
Переменные которые надо вставить в $config.dat

ENUM PROC_STATUS MAIN_UP, MAIN_DOWN, FORWARD200, UP100, RET_FORWARD200, RET_UP100
DECL E6POS UpperPos, LowerPos ;точки главной траектории
DECL PROC_STATUS ACT_STATUS, PRV_STATUS ;задаем переменные для хранения текущего и предыдущего статусов
DECL E6POS RetFw200, RetUp100 ;точки возврата из прерывания на главную траекторию

Сам исправленный пример:

DEF TestIRQ ( )
E6AXIS HOME
DECL INT sts

;FOLD INI;%{PE}
;FOLD BASISTECH INI
GLOBAL INTERRUPT DECL 3 WHEN $STOPMESS==TRUE DO IR_STOPM ( )
INTERRUPT ON 3
BAS (#INITMOV,0 )
;ENDFOLD (BASISTECH INI)
;FOLD USER INI
;Make your modifications here

;ENDFOLD (USER INI)
;ENDFOLD (INI)

;задаем прерывания
INTERRUPT DECL 5 WHEN $MEAS_PULSE[3]==TRUE DO IR_Forward200()
INTERRUPT DECL 4 WHEN $MEAS_PULSE[1]==TRUE DO IR_Up100()

sts = 0
RetFw200 = $NULLFRAME
RetUp100 = $NULLFRAME

$TOOL = TOOL_DATA[1]
$BASE = BASE_DATA[1]

HOME = {A1 0, A2 -90, A3 90, A4 90, A5 0, A6 0}
PTP HOME ;выйти на главную траекторию

;конвертируем HOME axis pos. в координаты верхней точки
UpperPos = FORWARD(HOME, sts)

;задаем нижнюю точку
LowerPos = UpperPos
LowerPos.Z = LowerPos.Z - 2000

;начальный статус движения (предполагаем, что робот вверху)
ACT_STATUS = #MAIN_DOWN
PRV_STATUS = ACT_STATUS
INTERRUPT ON 5
$ADVANCE = 0

LOOP
;статус менеджер
SWITCH ACT_STATUS
CASE #MAIN_DOWN
MainMoveDown() ;едем вниз и ждем срабатывания 5 прерывания
CASE #MAIN_UP
MainMoveUp() ;едем вверх и ждем срабатывания 5 прерывания
CASE #FORWARD200
Forward200() ;5 прерывание сработало, едем вперед и ждем срабатывания 4 прерывания
CASE #RET_FORWARD200
RetForward200() ;выходим на главную траекторию после движения вперед
CASE #UP100
Up100() ;4 прерывание сработало, движениу вперед остановлено, едем вверх
CASE #RET_UP100
RetUp100() ;возвращаемся вниз к точке срабатывания 4 прерывания
ENDSWITCH

WAIT FOR TRUE
ENDLOOP

END

;вниз по главной траектории
DEF MainMoveDown()
LIN LowerPos
ACT_STATUS = #MAIN_UP
END

;вверх по главной траектории
DEF MainMoveUp()
LIN UpperPos
ACT_STATUS = #MAIN_DOWN
END

;обработчик 5 прерывания
DEF IR_Forward200()
BRAKE F
$OV_PRO=100
INTERRUPT OFF 5
INTERRUPT ON 4
RetFw200 = $POS_RET
PRV_STATUS = ACT_STATUS
ACT_STATUS = #FORWARD200
RESUME
END

;обработчик 4 прерывания
DEF IR_Up100()
BRAKE F
RetUp100 = $POS_RET
ACT_STATUS = #UP100
RESUME
END

;просто вперед на 200 мм
DEF Forward200()
LIN_REL {X 200}
ACT_STATUS = #RET_FORWARD200
END

;назад к точке возврата из 5 прерывания
DEF RetForward200()
LIN RetFw200
INTERRUPT OFF 4
INTERRUPT ON 5
$OV_PRO=80
ACT_STATUS = PRV_STATUS ;продолжить прерванное движение: или вверх или вниз
END

;просто вверх на 100 мм
DEF Up100()
LIN_REL {Z 100}
ACT_STATUS = #RET_UP100
END

;назад к точке возврата из 4 прерывания
DEF RetUp100()
LIN RetUp100
ACT_STATUS = #RET_FORWARD200
END

sheppard
12.09.2020, 17:46
любопытственно! изучаю...