Uploaded image for project: 'Data Management'
  1. Data Management
  2. DM-21467

Write a simulator for the MT hexapod and rotator TCP/IP interface

    XMLWordPrintable

    Details

    • Type: Story
    • Status: Done
    • Resolution: Done
    • Fix Version/s: None
    • Component/s: ts_main_telescope
    • Labels:
      None
    • Story Points:
      4
    • Sprint:
      TSSW Sprint - Sep 29 - Oct 13
    • Team:
      Telescope and Site

      Description

      Write a simulator for the vendor's MT hexapod and rotator TCP/IP interface and code that talks to it. Test it on real hardware.

      This will help inform the total time required to write a simulator for these devices and the best approach to such a simulator.

        Attachments

          Issue Links

            Activity

            Hide
            rowen Russell Owen added a comment - - edited

            See https://confluence.lsstcorp.org/display/LTS/MT+Rotator+and+Hexapod+Notes

            I created a new package ts_pymoog to contain base classes for TCP/IP communication – both a server that runs in the CSC and a client for simulating the low level controller code in the cRIOs.

            Pull request: https://github.com/lsst-ts/ts_pymoog/pull/1

            To see how this is used see DM-21694, especially the pull request https://github.com/lsst-ts/ts_rotator/pull/5

            Show
            rowen Russell Owen added a comment - - edited See https://confluence.lsstcorp.org/display/LTS/MT+Rotator+and+Hexapod+Notes I created a new package ts_pymoog to contain base classes for TCP/IP communication – both a server that runs in the CSC and a client for simulating the low level controller code in the cRIOs. Pull request: https://github.com/lsst-ts/ts_pymoog/pull/1 To see how this is used see DM-21694 , especially the pull request https://github.com/lsst-ts/ts_rotator/pull/5
            Hide
            ttsai Te-Wei Tsai added a comment -

            The code in PR looks good and fulfill the ticket description. Great job done!

            Show
            ttsai Te-Wei Tsai added a comment - The code in PR looks good and fulfill the ticket description. Great job done!
            Hide
            rowen Russell Owen added a comment -

            Many thanks to Te-Wei Tsai for the following detailed review (with permission):

            1. I am confused for the package name: ts_pymoog. Moog code contains (1) middleware, (2) wrapper, and (3) LabVIEW GUI. It looks like you try to do something like ts_ctrl_crio_moog.

            2. This sentence is misleading:
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR12
            In Moog's code, it is three (not "each") cRIO controllers communicates over TCP/IP with a Commandable SAL Component (CSC = middleware).

            3. I am not sure we should use the word of "simulate" or "emulate" here:
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR15
            The emulator has the meaning to mimic the hardware behavior that this PR does not look like trying to do that. For example, Android emulator gives certain behavior of hardware phone already:
            https://developer.android.com/studio/run/emulator
            But when I reviewed your code, if you only want to consider the behavior of TCP/IP client, it did look like a TCP/IP client "emulator".
            I do see some simulation of the behavior here:
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-cf112886b18d8fd2b0df1c3d7c312112R88-R96
            If this is the case, maybe the term of emulate is good here.

            4. For the middleware by Moog, you never get the feedback from cRIO for "rejected command":
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR29

            5. Moog provides the CSC, not "CSCs". There is only one middleware:
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR37

            6. Moog only provides a single "CSC" (commandable SAL commonent), which is "middleware" here. The "wrapper" in Moog's documentation means the code deployed in the cRIO.
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR38
            PS. I have no real opinion to use the terms of middleware, wrapper, or CSC here. I just feel if we do not want to be consistent with the terminology, the future's developers/ maintainers will be super-confused. I stick to the documentation of Moog at this moment. If you prefer to use your own terminologies, we need to discuss how to update the documentation from Moog. Otherwise, it will be a big trouble in the future.

            7. Do you add this salobj to the table file as the required package?
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR29
            I do not see that actually:
            https://github.com/lsst-ts/ts_pymoog/blob/tickets/DM-21467/ups/ts_pymoog.table

            8. I do not understand the meaning of header here:
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR75

            9. I thought the self.cmd_reader need to be closed as the self.cmd_writer. But it looks like no thread for the self.cmd_reader. Is this correct?
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR127
            The same question for the self.tel_reader:
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR129
            PS. I thought I understand you meaning here:
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR164-R165
            Do you want to consider to add the comments on: self.cmd_writer.close() to say the self.cmd_reader will be closed as well?

            10. What is "coros"?
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR143

            11. Do you want to explain the header details in the docstring:
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR215
            Android DevelopersAndroid Developers
            Run apps on the Android Emulator | Android Developers
            The Android Emulator simulates Android devices on your computer so that you can test your application on a variety of devices and Android API levels without needing to have each physical device.(20 kB)

            12. Where is the input: "reader" to be used?
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-550eff8130d42c87e273101c19320703R73

            13. I know the message is a c structure (struct):
            https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-a9c28ca716bb24706e5dac2c9569dcbaR27
            But I thought it could be named like the cmd_msg to abstract the input to give more readability. But this is personal preference.

            14. It looks like you try to use async (single thread) to simulate the behavior of two threads. Will we have the performance issue?

            Show
            rowen Russell Owen added a comment - Many thanks to Te-Wei Tsai for the following detailed review (with permission): 1. I am confused for the package name: ts_pymoog. Moog code contains (1) middleware, (2) wrapper, and (3) LabVIEW GUI. It looks like you try to do something like ts_ctrl_crio_moog. 2. This sentence is misleading: https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR12 In Moog's code, it is three (not "each") cRIO controllers communicates over TCP/IP with a Commandable SAL Component (CSC = middleware). 3. I am not sure we should use the word of "simulate" or "emulate" here: https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR15 The emulator has the meaning to mimic the hardware behavior that this PR does not look like trying to do that. For example, Android emulator gives certain behavior of hardware phone already: https://developer.android.com/studio/run/emulator But when I reviewed your code, if you only want to consider the behavior of TCP/IP client, it did look like a TCP/IP client "emulator". I do see some simulation of the behavior here: https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-cf112886b18d8fd2b0df1c3d7c312112R88-R96 If this is the case, maybe the term of emulate is good here. 4. For the middleware by Moog, you never get the feedback from cRIO for "rejected command": https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR29 5. Moog provides the CSC, not "CSCs". There is only one middleware: https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR37 6. Moog only provides a single "CSC" (commandable SAL commonent), which is "middleware" here. The "wrapper" in Moog's documentation means the code deployed in the cRIO. https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-752cfbb96342b26a63548167f8d66defR38 PS. I have no real opinion to use the terms of middleware, wrapper, or CSC here. I just feel if we do not want to be consistent with the terminology, the future's developers/ maintainers will be super-confused. I stick to the documentation of Moog at this moment. If you prefer to use your own terminologies, we need to discuss how to update the documentation from Moog. Otherwise, it will be a big trouble in the future. 7. Do you add this salobj to the table file as the required package? https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR29 I do not see that actually: https://github.com/lsst-ts/ts_pymoog/blob/tickets/DM-21467/ups/ts_pymoog.table 8. I do not understand the meaning of header here: https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR75 9. I thought the self.cmd_reader need to be closed as the self.cmd_writer. But it looks like no thread for the self.cmd_reader. Is this correct? https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR127 The same question for the self.tel_reader: https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR129 PS. I thought I understand you meaning here: https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR164-R165 Do you want to consider to add the comments on: self.cmd_writer.close() to say the self.cmd_reader will be closed as well? 10. What is "coros"? https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR143 11. Do you want to explain the header details in the docstring: https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-30051fa9dcb1d0e34839888ba150974fR215 Android DevelopersAndroid Developers Run apps on the Android Emulator | Android Developers The Android Emulator simulates Android devices on your computer so that you can test your application on a variety of devices and Android API levels without needing to have each physical device.(20 kB) 12. Where is the input: "reader" to be used? https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-550eff8130d42c87e273101c19320703R73 13. I know the message is a c structure (struct): https://github.com/lsst-ts/ts_pymoog/pull/1/files#diff-a9c28ca716bb24706e5dac2c9569dcbaR27 But I thought it could be named like the cmd_msg to abstract the input to give more readability. But this is personal preference. 14. It looks like you try to use async (single thread) to simulate the behavior of two threads. Will we have the performance issue?
            Hide
            rowen Russell Owen added a comment - - edited

            1. I agree with you; I do not like the name ts_pymoog. However I would like to avoid underscores in package names implies sub-package namespaces (at least the way we do things), for example ts_ctrl_crio_moog implies lsst.ts.ctrl.crio.moog.

            After discussion with several people I have renamed the package to ts_hexrotcomm.

            2, 5 and 6: In my opinion the Moog "wrapper" code implements three different CSCs. Each has its own states and SAL topics. It is an internal detail that these CSCs are all running in the same process. The only clue for the user is that if one brings down the "wrapper" all three CSCs go away.

            I have tried to update my documentation to make that clearer.

            3. I have decided to go with "mock" everywhere. I think "emulate" is also a reasonable term, but CSCs have a simulation mode, so I prefer to restrict the number of terms to "simulate" and "mock". I could get rid of mock as well, but it is common and I prefer BaseMockController to BaseControllerSimulator or BaseSimulatedController.

            4. I did not understand your point so I asked offline. Here is my understanding now:

            The current CSCs (middleware) always say that acknowledge a command as succeeded even if it is rejected. They output the rejectedCommand event to reject a command.

            These details are out of scope for this package, but I will say that I find this behavior undesirable. My plan for my rotator and hexapod CSCs to properly reject commands when they can do so.

            7. Good catch. I changed to the code to not use salobj, as it seems silly to require the package just for this.

            8. Excellent point. I added a code comment that I hope will explain what is going on.

            9. I initially thought that readers should be closed, but it turns out that asyncio socket readers cannot be closed; they have no close method.

            10. "coros" means "coroutines". I will rename the variable to coroutines. (Note that "coro" is a common abbreviation in Python asyncio examples, but even so, I hope this makes the code easier to read).

            11. I hope it be clearer now that I have clarified item 8.

            12. Excellent point and I see that the doc string for set_command_writer is wrong, as well. I updated the doc strings to document the parameters and explain why the arguments are ignored. For the record these are called by asyncio.start_server which provides both a reader and a writer.

            13. Good point. I tried changing struct to cstruct everywhere but I felt it hampered readability. I am not keen to add the underscore, so I plan to stick with struct despite some reservations.

            14. I think asyncio can easily support these data rates. A timing test in salobj shows that one process can both produce and consume DDS messages at a rate of over 5000 messages/second. I would expect TCP/IP to do even better, though perhaps the use of ctypes to encode and decode the data might be a factor (I have not timed that).

            Although it is possible to run higher data rates for debugging, the standard rate is 20 Hz and I feel if the CSCs can reliably keep up with that then we should be in fine shape.

            Show
            rowen Russell Owen added a comment - - edited 1. I agree with you; I do not like the name ts_pymoog. However I would like to avoid underscores in package names implies sub-package namespaces (at least the way we do things), for example ts_ctrl_crio_moog implies lsst.ts.ctrl.crio.moog. After discussion with several people I have renamed the package to ts_hexrotcomm . 2, 5 and 6: In my opinion the Moog "wrapper" code implements three different CSCs. Each has its own states and SAL topics. It is an internal detail that these CSCs are all running in the same process. The only clue for the user is that if one brings down the "wrapper" all three CSCs go away. I have tried to update my documentation to make that clearer. 3. I have decided to go with "mock" everywhere. I think "emulate" is also a reasonable term, but CSCs have a simulation mode , so I prefer to restrict the number of terms to "simulate" and "mock". I could get rid of mock as well, but it is common and I prefer BaseMockController to BaseControllerSimulator or BaseSimulatedController . 4. I did not understand your point so I asked offline. Here is my understanding now: The current CSCs (middleware) always say that acknowledge a command as succeeded even if it is rejected. They output the rejectedCommand event to reject a command. These details are out of scope for this package, but I will say that I find this behavior undesirable. My plan for my rotator and hexapod CSCs to properly reject commands when they can do so. 7. Good catch. I changed to the code to not use salobj, as it seems silly to require the package just for this. 8. Excellent point. I added a code comment that I hope will explain what is going on. 9. I initially thought that readers should be closed, but it turns out that asyncio socket readers cannot be closed; they have no close method. 10. "coros" means "coroutines". I will rename the variable to coroutines . (Note that "coro" is a common abbreviation in Python asyncio examples, but even so, I hope this makes the code easier to read). 11. I hope it be clearer now that I have clarified item 8. 12. Excellent point and I see that the doc string for set_command_writer is wrong, as well. I updated the doc strings to document the parameters and explain why the arguments are ignored. For the record these are called by asyncio.start_server which provides both a reader and a writer. 13. Good point. I tried changing struct to cstruct everywhere but I felt it hampered readability. I am not keen to add the underscore, so I plan to stick with struct despite some reservations. 14. I think asyncio can easily support these data rates. A timing test in salobj shows that one process can both produce and consume DDS messages at a rate of over 5000 messages/second. I would expect TCP/IP to do even better, though perhaps the use of ctypes to encode and decode the data might be a factor (I have not timed that). Although it is possible to run higher data rates for debugging, the standard rate is 20 Hz and I feel if the CSCs can reliably keep up with that then we should be in fine shape.
            Hide
            rowen Russell Owen added a comment -

            Could you please have another look? The pull request is now: https://github.com/lsst-ts/ts_hexrotcomm/pull/1

            Show
            rowen Russell Owen added a comment - Could you please have another look? The pull request is now: https://github.com/lsst-ts/ts_hexrotcomm/pull/1
            Hide
            ttsai Te-Wei Tsai added a comment -

            This looks good to me now! Great job!

            Show
            ttsai Te-Wei Tsai added a comment - This looks good to me now! Great job!
            Hide
            ttsai Te-Wei Tsai added a comment -

            The PR is updated based on the discussion between Russell and my. The code and documentation looks good now!

             

            Show
            ttsai Te-Wei Tsai added a comment - The PR is updated based on the discussion between Russell and my. The code and documentation looks good now!  
            Hide
            rowen Russell Owen added a comment -

            Merged to develop.

            Show
            rowen Russell Owen added a comment - Merged to develop.

              People

              Assignee:
              rowen Russell Owen
              Reporter:
              rowen Russell Owen
              Reviewers:
              Te-Wei Tsai
              Watchers:
              Russell Owen, Te-Wei Tsai
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Jenkins

                  No builds found.