Страница 3 из 10
Re: Python в LinuxCnC
Добавлено: 28 май 2012, 17:02
nkp
Nick писал(а):Кстати, а как axis Gкод парсит?
Наверное с помощью модуля "gcode".
Код: Выделить всё
>>> import gcode
>>> dir (gcode)
['MAX_ERROR', 'MIN_ERROR', '__doc__', '__file__', '__name__', '__package__', 'arc_to_segments', 'calc_extents', 'linecode', 'parse', 'strerror']
>>>
Re: Python в LinuxCnC
Добавлено: 28 май 2012, 17:40
Nick
о, а вот это интересно

Re: Python в LinuxCnC
Добавлено: 28 май 2012, 17:50
Serg
Парсер питона на lexx написан.

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

Re: Python в LinuxCnC
Добавлено: 29 май 2012, 10:31
nkp
Вытянуть готовую траекторию из емс- действительно универсальнейшее средство для решения вопросы обр отхода(и не только)
Програмный анализ ж-кода крайне затруднителен с наличием в последнем о-кодов,пользовательских кодов и т.д.
А в случае с готовой траекторией-это все не имеет значения.
Надо двигаться в этом направлении .(и сразу вопрос-где в исходниках найти модуль "gcode" ?-мои поиски не дали результ)
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 10:58
Nick
вот и я что-то не нашел....
сделай у себя на компе с linuxCNC
ls /usr/lib/python2.6/ - по идее этот модуль должен где-то там лежать....
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 11:04
nkp
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 11:26
Nick
похоже вот он:
http://git.linuxcnc.org/gitweb?p=linuxc ... 1b;hb=HEAD
Я думаю проще попробовать из axis.py выдрать кусок, в котором он парсит gкод.
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 11:38
nkp
Вот некоторые функции
(для просмотра содержимого нажмите на ссылку)Код: Выделить всё
def parse_gcode_expression(e):
f = os.path.devnull
canon = DummyCanon()
parameter = inifile.find("RS274NGC", "PARAMETER_FILE")
temp_parameter = os.path.join(tempdir, os.path.basename(parameter))
shutil.copy(parameter, temp_parameter)
canon.parameter_file = temp_parameter
result, seq = gcode.parse("", canon, "M199 P["+e+"]", "M2")
if result > gcode.MIN_ERROR: return False, gcode.strerror(result)
return True, canon.number
Код: Выделить всё
def gcode_properties(event=None):
props = {}
if not loaded_file:
props['name'] = _("No file loaded")
else:
ext = os.path.splitext(loaded_file)[1]
program_filter = None
if ext:
program_filter = inifile.find("FILTER", ext[1:])
name = os.path.basename(loaded_file)
if program_filter:
props['name'] = _("generated from %s") % name
else:
props['name'] = name
size = os.stat(loaded_file).st_size
lines = int(widgets.text.index("end").split(".")[0])-2
props['size'] = _("%(size)s bytes\n%(lines)s gcode lines") % {'size': size, 'lines': lines}
if vars.metric.get():
conv = 1
units = _("mm")
fmt = "%.3f"
else:
conv = 1/25.4
units = _("in")
fmt = "%.4f"
mf = vars.max_speed.get()
#print o.canon.traverse[0]
g0 = sum(dist(l[1][:3], l[2][:3]) for l in o.canon.traverse)
g1 = (sum(dist(l[1][:3], l[2][:3]) for l in o.canon.feed) +
sum(dist(l[1][:3], l[2][:3]) for l in o.canon.arcfeed))
gt = (sum(dist(l[1][:3], l[2][:3])/min(mf, l[3]) for l in o.canon.feed) +
sum(dist(l[1][:3], l[2][:3])/min(mf, l[3]) for l in o.canon.arcfeed) +
sum(dist(l[1][:3], l[2][:3])/mf for l in o.canon.traverse) +
o.canon.dwell_time
)
props['g0'] = "%f %s".replace("%f", fmt) % (from_internal_linear_unit(g0, conv), units)
props['g1'] = "%f %s".replace("%f", fmt) % (from_internal_linear_unit(g1, conv), units)
if gt > 120:
props['run'] = _("%.1f minutes") % (gt/60)
else:
props['run'] = _("%d seconds") % (int(gt))
min_extents = from_internal_units(o.canon.min_extents, conv)
max_extents = from_internal_units(o.canon.max_extents, conv)
for (i, c) in enumerate("xyz"):
a = min_extents[i]
b = max_extents[i]
if a != b:
props[c] = _("%(a)f to %(b)f = %(diff)f %(units)s").replace("%f", fmt) % {'a': a, 'b': b, 'diff': b-a, 'units': units}
properties(root_window, _("G-Code Properties"), property_names, props)
Код: Выделить всё
def save_gcode(*args):
if not loaded_file: return
global open_directory
f = root_window.tk.call("tk_getSaveFile", "-initialdir", open_directory,
"-filetypes", ((_("rs274ngc files"), ".ngc"),))
if not f: return
f = unicode(f)
open_directory = os.path.dirname(f)
if get_filter(loaded_file):
srcfile = os.path.join(tempdir, os.path.basename(loaded_file))
else:
srcfile = loaded_file
try:
shutil.copy(srcfile, f)
except (shutil.Error, os.error, IOError), detail:
tb = traceback.format_exc()
root_window.tk.call("nf_dialog", ".error", _("Error saving file"),
str(detail), "error", 0, _("OK"))
else:
add_recent_file(f)
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 11:45
nkp
Я так понимаю- функция должна вернуть траекторию в виде массива координат опорных точек.?
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 11:56
Nick
nkp писал(а): result, seq = gcode.parse("", canon, "M199 P["+e+"]", "M2")
Что-то я этого не понимаю...
И что такое canon, есть мысли?
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 11:57
Nick
О, есть еще вот такая штука:
Код: Выделить всё
1576 def load_preview(self, f, canon, unitcode, initcode, interpname=""):
1577 self.set_canon(canon)
1578 result, seq = gcode.parse(f, canon, unitcode, initcode, interpname)
1579
1580 if result <= gcode.MIN_ERROR:
1581 self.canon.progress.nextphase(1)
1582 canon.calc_extents()
1583 self.stale_dlist('program_rapids')
1584 self.stale_dlist('program_norapids')
1585 self.stale_dlist('select_rapids')
1586 self.stale_dlist('select_norapids')
1587
1588 return result, seq
Вот тут:
http://git.linuxcnc.org/gitweb?p=linuxc ... glcanon.py
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 12:02
Nick
при этом unitcode и initcode можно взять отсюда:
Код: Выделить всё
1102 initcode = inifile.find("EMC", "RS274NGC_STARTUP_CODE") or ""
1103 if initcode == "":
1104 initcode = inifile.find("RS274NGC", "RS274NGC_STARTUP_CODE") or ""
1105 if not interpname:
1106 unitcode = "G%d" % (20 + (s.linear_units == 1))
1107 else:
1108 unitcode = ''"
interpname:
Код: Выделить всё
2869 interpname = inifile.find("TASK", "INTERPRETER") or ""
осталось понять, что такое canon и можно начинать мучить вывод parse

Re: Python в LinuxCnC
Добавлено: 29 май 2012, 12:11
nkp
А не ложный ли это след?
Axis ли занимается траекторией? В таком случае в другие интерфейсы (мини,ткемс...) это должно быть встроено.
Axis нужна траектория для графического отображения ее. зачем тогда axis парсит ж-код?
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 12:14
Nick
nkp писал(а):Axis ли занимается траекторией? В таком случае в другие интерфейсы (мини,ткемс...) это должно быть встроено.
А остальные не строят траекторию. Насколько я помню tkEMC строит только live plot, т.е. только запоминает где он уже проехал.
nkp писал(а):Axis нужна траектория для графического отображения ее. зачем тогда axis парсит ж-код?
А как получить траекторию не отпарсив Gкод?
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 14:55
Serg
Nick писал(а):
осталось понять, что такое canon и можно начинать мучить вывод parse

canon - это объект/класс, описывающий координаты станка, он-же переводит координаты в движение осей и много чего ещё из этой области. От слов "canonical commands".
Это результат взгляда "по диагонали" на исходники.
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 14:58
Serg
Nick писал(а):
А как получить траекторию не отпарсив Gкод?
А можно-же как-то запросить коорднаты места, где закончилось выполнение последнего кадра?
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 15:33
Nick
можно взять текущие координаты из hal, но не факт, что они будут совпадать с координатами прописанными в Gкоде. Т.к. есть отступы, системы координат и прочее. Их значения по идее можно получить, но надо будет их отдельно обрабатывать...
canon - это объект/класс, описывающий координаты станка, он-же переводит координаты в движение осей и много чего ещё из этой области. От слов "canonical commands".
В принципе для нас это наверное не сильно важно, если мы просто хотим инвертировать траекторию... Т.е. наверное можно использовать что-то типа этого куска axis:
Код: Выделить всё
class DummyCanon:
1341 def comment(*args): pass
1342 def next_line(*args): pass
1343 def set_g5x_offset(*args): pass
1344 def set_g92_offset(*args): pass
1345 def set_xy_rotation(*args): pass
1346 def get_external_angular_units(self): return 1.0
1347 def get_external_length_units(self): return 1.0
1348 def set_plane(*args): pass
1349 def get_axis_mask(self): return 7
1350 def get_tool(self, tool):
1351 return tool, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0
1352 def set_feed_rate(self, rate): pass
1353
1354 def user_defined_function(self, m, p, q):
1355 self.number = p
canon = DummyCanon()
s3301 писал(а):Это результат взгляда "по диагонали" на исходники.
Эх вот бы было где-то описание всех этих модулей

...
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 21:03
Serg
Nick писал(а):можно взять текущие координаты из hal, но не факт, что они будут совпадать с координатами прописанными в Gкоде. Т.к. есть отступы, системы координат и прочее. Их значения по идее можно получить, но надо будет их отдельно обрабатывать...
Собственно идея непродуманная, а потому может глупая: Между исполнениями кадров записывать координаты инструмента, т.е. в процессе выполнения сохраняется такая последовательность координат и номеров кадров: коорд0,кадр1,коорд1,кадр2,коорд2,кадр3,...
Если что-то сломалось например при выполнении кадра 123, то записываемая последовательность заканчивается на "...,коорд122,кадр123" - устраняем поломку, определяем начало координат, едем в точку коорд122 и продолжаем работу с выполнения кадр123.
Re: Python в LinuxCnC
Добавлено: 29 май 2012, 21:38
nkp
s3301 писал(а): Между исполнениями кадров записывать координаты
И я думаю,что в этом есть смысл.Можно делать на лету,а можно -по желанию(ну допустим деталь
дорогая ответственная) прогнать запись предварительно.Надо попробовать.
Re: Python в LinuxCnC
Добавлено: 30 май 2012, 12:53
nkp
nkp писал(а):Надо попробовать.
Вот результаты(предварительно):
Скрипт:
(для просмотра содержимого нажмите на ссылку)Код: Выделить всё
import time
from subprocess import Popen, PIPE
f = open(r'/home/nkp/emc2/nc_files/12.ngc','a')
idle=0
while idle==0 :
i= Popen('halcmd getp halui.program.is-idle ', shell=True, stdout=PIPE).stdout.read()
if i.find('FALSE')==-1 :
idle=1
else :
idle=0
if idle==0 :
time_step= Popen('halcmd getp motion.in-position ', shell=True, stdout=PIPE).stdout.read()
if time_step.find('TRUE')==-1 :
t_s=0
else :
t_s=1
if t_s==1 :
s1= Popen('halcmd setp halui.program.step 0 ', shell=True, stdout=PIPE).stdout.read()
p0= Popen('halcmd getp axis.0.joint-pos-cmd ', shell=True, stdout=PIPE).stdout.read()
n= Popen('halcmd getp minmax.0.max ', shell=True, stdout=PIPE).stdout.read()
time.sleep(1)
f.write(p0)
f.write(n)
s1= Popen('halcmd setp halui.program.step 1 ', shell=True, stdout=PIPE).stdout.read()
time.sleep(1)
else :
time.sleep(1)
else :
Popen('halcmd setp halui.program.stop 1 ', shell=True, stdout=PIPE).stdout.read()
f.close()
резутат (показан частично) :
Это для одной оси.