Coder Social home page Coder Social logo

2b-t / myactuator_rmd Goto Github PK

View Code? Open in Web Editor NEW
15.0 2.0 9.0 319 KB

C++ and Python SDK for controlling actuators of the MyActuator RMD-X series, written in C++ with Python bindings

License: MIT License

CMake 2.39% C++ 96.52% Python 1.09%
actuator can canbus cpp driver mit-cheetah rmd rmd-x8 ros ros2

myactuator_rmd's People

Contributors

2b-t avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

myactuator_rmd's Issues

Python bindings usage fails

The python bindings fail when creating new driver.

Python 3.12.3 (main, June 19 2024, 05:33:47) [GCC 13.2.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.20.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import myactuator_rmd_py as myactuator_rmd

In [2]: driver1 = myactuator_rmd.Driver('can0', 1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 1
----> 1 driver1 = myactuator_rmd.Driver('can0', 1)

TypeError: myactuator_rmd_py.Driver: No constructor defined!

In [3]: dir(myactuator_rmd)
Out[3]: 
['ActuatorException',
 'ActuatorInterface',
 'CanDriver',
 'Driver',
 'ProtocolException',
 'ValueRangeException',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 'actuator_constants',
 'actuator_state',
 'can']

Compile error Rpi4

Hello, thanks for the amazing work.
I am trying to compile the project in a Rpi4 and getting the following error:

(venv_strummer) metal@raspberrypi:~/Documents/strummer/myactuator_rmd/build $ make -j $(nproc)
[ 25%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/protocol/responses.cpp.o
[ 25%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/protocol/requests.cpp.o
[ 37%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/driver.cpp.o
In file included from /home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/single_motor_message.hpp:17,
                 from /home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/requests.hpp:20,
                 from /home/metal/Documents/strummer/myactuator_rmd/src/protocol/requests.cpp:1:
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:94:77: error: redefinition of default argument for ‘std::enable_if_t<is_integral_v<T> >* <anonymous>’
   94 |   template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                             ^~~~~~~
In file included from /home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/single_motor_message.hpp:17,
                 from /home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/responses.hpp:23,
                 from /home/metal/Documents/strummer/myactuator_rmd/src/protocol/responses.cpp:1:
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:94:77: error: redefinition of default argument for ‘std::enable_if_t<is_integral_v<T> >* <anonymous>’
   94 |   template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                             ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:65:81: note: original definition appeared here
   65 |       template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                                 ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:65:81: note: original definition appeared here
   65 |       template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                                 ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:103:77: error: redefinition of default argument for ‘std::enable_if_t<is_integral_v<T> >* <anonymous>’
  103 |   template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                             ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:103:77: error: redefinition of default argument for ‘std::enable_if_t<is_integral_v<T> >* <anonymous>’
  103 |   template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                             ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:79:81: note: original definition appeared here
   79 |       template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                                 ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:79:81: note: original definition appeared here
   79 |       template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                                 ^~~~~~~
In file included from /home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/node.hpp:18,
                 from /home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/driver.hpp:26,
                 from /home/metal/Documents/strummer/myactuator_rmd/src/driver.cpp:1:
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:94:77: error: redefinition of default argument for ‘std::enable_if_t<is_integral_v<T> >* <anonymous>’
   94 |   template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                             ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:65:81: note: original definition appeared here
   65 |       template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                                 ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:103:77: error: redefinition of default argument for ‘std::enable_if_t<is_integral_v<T> >* <anonymous>’
  103 |   template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                             ^~~~~~~
/home/metal/Documents/strummer/myactuator_rmd/include/myactuator_rmd/protocol/message.hpp:79:81: note: original definition appeared here
   79 |       template <typename T, typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
      |                                                                                 ^~~~~~~
make[2]: *** [CMakeFiles/myactuator_rmd.dir/build.make:118: CMakeFiles/myactuator_rmd.dir/src/protocol/responses.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: *** [CMakeFiles/myactuator_rmd.dir/build.make:104: CMakeFiles/myactuator_rmd.dir/src/protocol/requests.cpp.o] Error 1
make[2]: *** [CMakeFiles/myactuator_rmd.dir/build.make:132: CMakeFiles/myactuator_rmd.dir/src/driver.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/myactuator_rmd.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

Error installing python package or building C++ library: ‘struct can_frame’ has no member named ‘len’

Hello,

I'm trying to install as a Python package, but I'm getting an error I don't know how to resolve when I do pip3 install .. I think the key error is /home/user/ContinuO_Python/myactuator_rmd/src/can/node.cpp:150:13: error: ‘struct can_frame’ has no member named ‘len’, but I'm not certain.

I'm on Ubuntu 20.04, and I should have all dependencies installed (I had to compile cmake >= 3.20 from source and install as a DEB package). One caveat is that I'm on a lowlatency kernel and when I attempt to execute sudo apt-get install linux-modules-extra-$(uname -r) I get E: Package 'linux-modules-extra-5.15.0-110-lowlatency' has no installation candidate.

My output:

Processing /home/user/ContinuO_Python/myactuator_rmd
  Installing build dependencies ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Building wheels for collected packages: myactuator_rmd_py
  Building wheel for myactuator_rmd_py (pyproject.toml) ... error
  error: subprocess-exited-with-error
  
  × Building wheel for myactuator_rmd_py (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [110 lines of output]
      running bdist_wheel
      running build
      running build_ext
      -- The C compiler identification is GNU 9.4.0
      -- The CXX compiler identification is GNU 9.4.0
      -- Detecting C compiler ABI info
      -- Detecting C compiler ABI info - done
      -- Check for working C compiler: /usr/bin/cc - skipped
      -- Detecting C compile features
      -- Detecting C compile features - done
      -- Detecting CXX compiler ABI info
      -- Detecting CXX compiler ABI info - done
      -- Check for working CXX compiler: /usr/bin/c++ - skipped
      -- Detecting CXX compile features
      -- Detecting CXX compile features - done
      -- Found Python: /home/user/ContinuO_Python/.venv/bin/python3 (found version "3.8.10") found components: Interpreter Development Development.Module Development.Embed
      CMake Deprecation Warning at /usr/lib/cmake/pybind11/pybind11Tools.cmake:8 (cmake_minimum_required):
        Compatibility with CMake < 3.5 will be removed from a future version of
        CMake.
      
        Update the VERSION argument <min> value or use a ...<max> suffix to tell
        CMake that the project does not need compatibility with older versions.
      Call Stack (most recent call first):
        /usr/lib/cmake/pybind11/pybind11Config.cmake:100 (include)
        CMakeLists.txt:56 (find_package)
      
      
      CMake Warning (dev) at /usr/lib/cmake/pybind11/FindPythonLibsNew.cmake:60 (find_package):
        Policy CMP0148 is not set: The FindPythonInterp and FindPythonLibs modules
        are removed.  Run "cmake --help-policy CMP0148" for policy details.  Use
        the cmake_policy command to set the policy and suppress this warning.
      
      Call Stack (most recent call first):
        /usr/lib/cmake/pybind11/pybind11Tools.cmake:16 (find_package)
        /usr/lib/cmake/pybind11/pybind11Config.cmake:100 (include)
        CMakeLists.txt:56 (find_package)
      This warning is for project developers.  Use -Wno-dev to suppress it.
      
      -- Found PythonInterp: /home/user/ContinuO_Python/.venv/bin/python (found version "3.8.10")
      -- Found PythonLibs: /usr/lib/x86_64-linux-gnu/libpython3.8.so
      -- Performing Test HAS_FLTO
      -- Performing Test HAS_FLTO - Success
      -- LTO enabled
      -- Configuring done (0.5s)
      -- Generating done (0.0s)
      -- Build files have been written to: /home/user/ContinuO_Python/myactuator_rmd/build/temp.linux-x86_64-cpython-38/myactuator_rmd_py
      [ 12%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/can/node.cpp.o
      /home/user/ContinuO_Python/myactuator_rmd/src/can/node.cpp: In member function ‘void myactuator_rmd::can::Node::write(uint32_t, const std::array<unsigned char, 8>&)’:
      /home/user/ContinuO_Python/myactuator_rmd/src/can/node.cpp:150:13: error: ‘struct can_frame’ has no member named ‘len’
        150 |       frame.len = 8;
            |             ^~~
      make[2]: *** [CMakeFiles/myactuator_rmd.dir/build.make:76: CMakeFiles/myactuator_rmd.dir/src/can/node.cpp.o] Error 1
      make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/myactuator_rmd.dir/all] Error 2
      make: *** [Makefile:136: all] Error 2
      Traceback (most recent call last):
        File "/home/user/ContinuO_Python/.venv/lib/python3.8/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 353, in <module>
          main()
        File "/home/user/ContinuO_Python/.venv/lib/python3.8/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File "/home/user/ContinuO_Python/.venv/lib/python3.8/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py", line 251, in build_wheel
          return _build_backend().build_wheel(wheel_directory, config_settings,
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 415, in build_wheel
          return self._build_with_temp_dir(
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 397, in _build_with_temp_dir
          self.run_setup()
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 497, in run_setup
          super().run_setup(setup_script=setup_script)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/build_meta.py", line 313, in run_setup
          exec(code, locals())
        File "<string>", line 56, in <module>
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/__init__.py", line 103, in setup
          return distutils.core.setup(**attrs)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 184, in setup
          return run_commands(dist)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/core.py", line 200, in run_commands
          dist.run_commands()
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 969, in run_commands
          self.run_command(cmd)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/dist.py", line 976, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/command/bdist_wheel.py", line 373, in run
          self.run_command("build")
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/cmd.py", line 316, in run_command
          self.distribution.run_command(command)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/dist.py", line 976, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/command/build.py", line 132, in run
          self.run_command(cmd_name)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/cmd.py", line 316, in run_command
          self.distribution.run_command(command)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/dist.py", line 976, in run_command
          super().run_command(command)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/dist.py", line 988, in run_command
          cmd_obj.run()
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/command/build_ext.py", line 93, in run
          _build_ext.run(self)
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/command/build_ext.py", line 359, in run
          self.build_extensions()
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/command/build_ext.py", line 479, in build_extensions
          self._build_extensions_serial()
        File "/tmp/pip-build-env-fib9wcpr/overlay/lib/python3.8/site-packages/setuptools/_distutils/command/build_ext.py", line 505, in _build_extensions_serial
          self.build_extension(ext)
        File "<string>", line 52, in build_extension
        File "/usr/lib/python3.8/subprocess.py", line 516, in run
          raise CalledProcessError(retcode, process.args,
      subprocess.CalledProcessError: Command '['cmake', '--build', '.']' returned non-zero exit status 2.
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
  ERROR: Failed building wheel for myactuator_rmd_py
Failed to build myactuator_rmd_py
ERROR: ERROR: Failed to build installable wheels for some pyproject.toml based projects (myactuator_rmd_py)

If I instead attempt to build as a C++ library with Python bindings on, I get a similar error after make:

(.venv) user@ContinuO-Laptop-Linux:~/ContinuO_Python/myactuator_rmd/build$ make -j $(nproc)
[ 12%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/can/node.cpp.o
[ 25%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/can/utilities.cpp.o
[ 37%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/protocol/requests.cpp.o
[ 50%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/protocol/responses.cpp.o
[ 62%] Building CXX object CMakeFiles/myactuator_rmd.dir/src/actuator_interface.cpp.o
/home/user/ContinuO_Python/myactuator_rmd/src/can/utilities.cpp: In function ‘std::ostream& operator<<(std::ostream&, const can_frame&)’:
/home/user/ContinuO_Python/myactuator_rmd/src/can/utilities.cpp:11:29: error: ‘const struct can_frame’ has no member named ‘len’
   11 |   for (int i = 0; i < frame.len; i++) {
      |                             ^~~
make[2]: *** [CMakeFiles/myactuator_rmd.dir/build.make:90: CMakeFiles/myactuator_rmd.dir/src/can/utilities.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
/home/user/ContinuO_Python/myactuator_rmd/src/can/node.cpp: In member function ‘void myactuator_rmd::can::Node::write(uint32_t, const std::array<unsigned char, 8>&)’:
/home/user/ContinuO_Python/myactuator_rmd/src/can/node.cpp:150:13: error: ‘struct can_frame’ has no member named ‘len’
  150 |       frame.len = 8;
      |             ^~~
make[2]: *** [CMakeFiles/myactuator_rmd.dir/build.make:76: CMakeFiles/myactuator_rmd.dir/src/can/node.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/myactuator_rmd.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

Thank you for your assistance, I'm a novice.

Exceptions: myactuator_rmd.can.BusError and ProtocolException on repeated path-following commands

Hi Tobit,

I am still investigating, but when using closed-loop position control for path-following (with commands every time step), my system tends to accrue many myactuator_rmd.can.BusError exceptions regardless of the time step size used (typically 2 ms but with other time step sizes also). I'm handling the exceptions and it doesn't appear to have a significant effect on path following performance, but after executing a path later individual commands often return a myactuator_rmd_py.ProtocolException: Unexpected response of the kind used by the path following, e.g.:

>>> motor[5].setAcceleration(5000, pos_accel)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
myactuator_rmd_py.ProtocolException: Unexpected response '0xa4'

In this case monitoring the CAN socket reveals a correct (0x43) message and response, and the motor does execute the command to write the new acceleration, but it is problematic when you need to read the correct response (e.g., with getMultiTurnAngle()). It is as though responses to commands which receive a BusError accrue in a buffer and then are inappropriately read by later commands.

Also, though more rarely, a BusError will occur on a command that is not repeated each time step, which I think may cause the command to fail to be sent to the motor (to be confirmed) - potentially disrupting a program. Anecdotally, I think the likelihood of this may increase as more BusError's have been accrued (e.g., following execution of a path).

As I mentioned I'm still investigating, so I'm not certain whether the bus errors are a result of something in my system or something in the code. I haven't yet dug into your code sufficiently to see what might cause the bus errors there, but maybe you have a better idea? In any case, I wonder if there is a way to clear the response buffer so later commands don't get unexpected responses?

I will continue to look into this on my return at the end of the month, but just wanted to bring it up now in case you have a chance to start thinking about it.

Cheers,
Stefan

Closed-loop position control mode jumping along a trajectory

Hello again Tobit,

I have been trying to use closed-loop position control commands (using your repo installed as a python package) to get a motor to follow a smooth position curve: as a simple test, a sin(t) curve with a typical time step of 1 ms (though I have tried various step sizes up to 0.1 s and down to 0.1 ms). Like this:

startup_pos = {}
for id in motor_IDs:
    startup_pos[id] = motor[id].getMultiTurnAngle()

t = 0
dt = 0.001

def sin_pos(t):
    max_angle = 30 # degrees
    freq = 0.5 # Hz
    return startup_pos[5] + max_angle * math.sin(2 * math.pi * freq * t)

while True:
    fr_knee.sendPositionAbsoluteSetpoint(sin_pos(t), 500)
    time.sleep(dt)
    t += dt

However, this results in my motor jumping to various positions along the expected curve and stopping at each for a moment (maybe about a half-second), like it is only receiving some of the commands and ignoring the others. The frequency of the jumps does not seem to vary with time step size that I can tell. Have you experienced similar? Do you know if there is a substantial delay between when these motors will accept new closed-loop position commands? I'm using several RMD-X8-Pro-H V3, and each I've tested has done the same.

I have also tried various max velocity inputs, which as expected changes the speed at which the motor jumps from one position to the other, but otherwise is the same.

I'm aware this may be an issue with the motor rather than with your repo, so I apologize if this is an inappropriate forum for this discussion. I just figured you may be knowledgeable, so it was worth asking. I have reached out to myactuator for comment also. If this is just a behaviour of the motor for this control mode, I would like to try Motion Control Mode as an alternative, thus #9.

Thanks again,
Stefan

Thank you! 💚

This is actually not an issue. I just wanted to say thank you for making this repository and for your incredible work. 🙌

(feel free to close it)

Constants for the X8-Pro-H V3 actuator

Hello,

I noticed a small inconsistency regarding the constants of the X8-Pro-H V3 motor, which seems very low to me. In the X8ProHV3 class, the torque constant of 0.29 Nm/A probably corresponds to the motor torque without a reducer.

The technical specifications also specify "motor" for this value,
Capture d'écran 2024-06-09 193417
while for the X8ProV2, the torque of 2.6 Nm/A is expressed without "motor".
Capture d'écran 2024-06-09 194707
This change in reference also seems to apply to the entire V3 range.

What do you think?

Best regards,

1320 dps enforcement - max speed check

Hi Tobit,

I am testing this SDK with a RMD-X6-S
This motor can in theory achive speeds of 6000RPM (36000dps)
I think it is not related but it comes with a newer version of the protocol V4.01

I am trying to achive high speeds with it.
Is there a reason for the speed check in the code
?

RDM-X6-P6

Feature Inquiry: Motion Mode Control Command

Hi Tobit,

I'm looking into ways to implement Motion Mode Control (i.e., send desired position and velocity with kp and kd and feedforward torque - 0x400 + ID in the control protocol). I've installed your repo as a python package and used it for position and velocity closed loop control, but unless I'm missing something the motion mode control command is not yet implemented. I've tried to puzzle out how I might modify your source to add the feature, but I'm a C++ novice so I haven't been able to figure it out (yet). Do you have any interest in developing this feature, or do you have any advice as to how I might get started doing so?

I'm aware this would at least require:

  • Allowing a set of CAN addresses with a 0x400 offset (i.e., 0x400 + ID);
  • Encoding inputs into the required data frame and transmitting to the CAN socket;
  • Receiving and decoding reply data;
  • Creating a python binding.

Thank you,
Stefan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.