Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CANParser: direct capnp to vector[CanData] conversion #1452

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

deanlee
Copy link
Contributor

@deanlee deanlee commented Nov 7, 2024

This PR simplifies the conversion process by eliminating unnecessary intermediate steps and directly converting Capnp data to vector[CanData] within the C++ space. Previously, the conversion involved multiple stages:

  1. capnp → vector[CanData] (C++)
  2. vector[CanData] → Python nested list (Cython)
  3. Python nested list → vector[CanData] (Cython)
  4. Passing vector[CanData] back to CanParser::update from Cython to C++

Now, the conversion occurs directly from capnp to vector[CanData], encapsulated within the ParsedCanData class, which passes the vector[CanData] by pointer. This approach simplifies the conversion pipeline and reduces overhead.

Key changes:

  1. Encapsulated vector[CanData] in ParsedCanData: (can_capnp_to_list: direct capnp to vector[CanData] conversion openpilot#33952)

    cdef class ParsedCanData:
      cdef vector[CanData] *data
    
      def __cinit__(self):
        self.data = new vector[CanData]()
    
      def __dealloc__(self):
        del self.data
    
      def get_data_pointer(self):
        return <uintptr_t> self.data
  2. Parse capnp data directly into ParsedCanData's member vector[CanData] in C++:

    def can_capnp_to_list(strings, msgtype='can'):
      cdef ParsedCanData result = ParsedCanData()
      can_capnp_to_can_list_cpp(strings, result.data[0], msgtype == 'sendcan')
      return result
  3. Efficiently pass the data pointer to CanParser.update:

    def update_strings(self, parsed_data, sendcan=False):
      cdef uintptr_t pointer = parsed_data.get_data_pointer()
      can_data = <vector[CanData]*> pointer
      return self._update(can_data[0], sendcan)

By removing the redundant conversion layers, this PR improves both performance and resource efficiency. The change is particularly beneficial for high-frequency CAN processing in real-time, on-device environments, resulting in faster execution and lower system overhead.

@github-actions github-actions bot added the can related to CAN tools, aka opendbc/can/ label Nov 7, 2024
@deanlee deanlee force-pushed the parser_pass_pointer branch 2 times, most recently from fe60520 to 8e30615 Compare November 7, 2024 04:38
@deanlee deanlee force-pushed the parser_pass_pointer branch 5 times, most recently from 9c08516 to f1d075c Compare November 7, 2024 05:01
@deanlee deanlee marked this pull request as ready for review November 7, 2024 05:42
@deanlee deanlee force-pushed the parser_pass_pointer branch 3 times, most recently from 31e7699 to 6c0c861 Compare November 10, 2024 12:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
can related to CAN tools, aka opendbc/can/ car related to opendbc/car/ chrysler ford gm honda hyundai toyota
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant