pcdshub / pytmc

Generate EPICS IOCs and records from TwinCAT projects - along with many TwinCAT project tools
https://pcdshub.github.io/pytmc/
Other
10 stars 11 forks source link

Pytmc fails on arrays of pointers to motors #168

Closed ZLLentz closed 4 years ago

ZLLentz commented 4 years ago

Desired behavior is to skip these kinds of objects. This one specifically is ARRAY [0..18] OF POINTER TO DUT_MotionStage. I'm happy to work on this tomorrow, just documenting for now.

From the bleeding edge LFE motion PLC:

$ make
-----------------------------------------------------------
Build path: /reg/neh/home4/zlentz/github/lcls-plc-lfe-motion/iocBoot/ioc-lfe-motion/.pytmc_build
PLC: lfe_motion
IOC name: ioc-lfe-motion
PYTMC_OPTS: 
PROJECT_PATH: ../../plc-lfe-motion/plc-lfe-motion.tsproj
Absolute project path:  /reg/neh/home4/zlentz/github/lcls-plc-lfe-motion/plc-lfe-motion/plc-lfe-motion.tsproj
-----------------------------------------------------------

mkdir -p "/reg/neh/home4/zlentz/github/lcls-plc-lfe-motion/iocBoot/ioc-lfe-motion/.pytmc_build"
Executing pytmc...
cd "/reg/neh/home4/zlentz/github/lcls-plc-lfe-motion/iocBoot/ioc-lfe-motion/.pytmc_build" && \
    pytmc stcmd \
    --name "ioc-lfe-motion" \
    --plc "lfe_motion" \
    --template-path "/reg/g/pcds/epics/ioc/common/ads-ioc/R0.1.6/iocBoot/templates" \
    --template "st.cmd.template" \
    --hashbang "/reg/g/pcds/epics/ioc/common/ads-ioc/R0.1.6/bin/rhel7-x86_64/adsIoc" \
    -p "PLC:LFE:MOTION" \
     \
    "/reg/neh/home4/zlentz/github/lcls-plc-lfe-motion/plc-lfe-motion/plc-lfe-motion.tsproj" > st.cmd
INFO:pytmc.bin.stcmd:Found 1705 additional records; writing to lfe_motion.db
Traceback (most recent call last):
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/jinja2/environment.py", line 411, in getitem
    return obj[argument]
TypeError: 'Symbol_DUT_MotionStage' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/bin/pytmc", line 11, in <module>
    load_entry_point('pytmc==2.5.0', 'console_scripts', 'pytmc')()
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/pytmc/bin/pytmc.py", line 92, in main
    func(**kwargs)
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/pytmc/bin/stcmd.py", line 293, in main
    raise stashed_exception
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/pytmc/bin/stcmd.py", line 286, in main
    rendered = template.render(**template_args)
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "/reg/g/pcds/epics/ioc/common/ads-ioc/R0.1.6/iocBoot/templates/st.cmd.template", line 90, in top-level template code
    {% for motor in symbols.Symbol_DUT_MotionStage | sort(attribute='nc_axis.axis_number') %}
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/jinja2/filters.py", line 278, in do_sort
    return sorted(value, key=key_func, reverse=reverse)
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/jinja2/filters.py", line 77, in attrgetter
    item = environment.getitem(item, part)
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/jinja2/environment.py", line 420, in getitem
    return getattr(obj, attr)
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/pytmc/parser.py", line 946, in nc_axis
    link = self.nc_to_plc_link
  File "/reg/g/pcds/pyps/conda/py36/envs/pcds-3.0.0/lib/python3.6/site-packages/pytmc/parser.py", line 938, in nc_to_plc_link
    raise RuntimeError(f'No NC link to DUT_MotionStage found for '
RuntimeError: No NC link to DUT_MotionStage found for 'PRG_AT2L0_SOLID.fbAT2L0_axes'
make: *** [build] Error 1
klauer commented 4 years ago

Thanks for the report! Let me know if you need help on the fix.

ZLLentz commented 4 years ago

Vague approach will be to see if I can get POINTER objects to be their own thing instead of becoming the type they are pointing to. As far as EPICS is concerned all of these are just representations of memory addresses, so they are an int type (of size that depends on the architecture)

ZLLentz commented 4 years ago

Looks like the information is clearly present in the symbol:

<Symbol>
    <Name>PRG_AT2L0_SOLID.fbAT2L0_axes</Name>
    <BitSize>608</BitSize>
    <BaseType PointerTo="1" Namespace="lcls_twincat_motion">DUT_MotionStage</BaseType>
    <ArrayInfo>
        <LBound>0</LBound>
        <Elements>19</Elements>
    </ArrayInfo>
    <BitOffs>7219456</BitOffs>
</Symbol>
ZLLentz commented 4 years ago

The approach I'm actually going to pursue is to add a property that tells us if a symbol is a pointer or not, mirroring the PointerTo attribute in the xml. Then, in the st.cmd.template jinja we would skip over motors that are pointers.