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

CAN Bus Communication for Multiple VESCs #104

Open
kyleoptimotive opened this issue Dec 2, 2024 · 2 comments
Open

CAN Bus Communication for Multiple VESCs #104

kyleoptimotive opened this issue Dec 2, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@kyleoptimotive
Copy link

Abstract

I want to expose vesc hw interfaces to ROS for one master VESC and 'n' other VESCs connected via CAN bus. Do you have any suggestions for how I might start this?

Purpose

To expose vesc hw interfaces in ROS for multiple vesc devices where only one is connected to the host PC via USB and the rest are connected to that vesc over CAN bus. This allows multiple vescs to be used without needing each one to be plugged in via USB to the host PC.

Implementation Details

I am using ROS Humble and Ubuntu 22.04.

@kyleoptimotive kyleoptimotive added the enhancement New feature or request label Dec 2, 2024
@Jha1005
Copy link

Jha1005 commented Dec 13, 2024

I am also using also ros2 humble.Can you suggest me i have 3 vesc and i have to run it on canbus so what changes or includation i have to do ??

@kyleoptimotive
Copy link
Author

I've done some experimentation and worked out a way to use vesc_hw_interface to talk to all VESCs as if they are one device. This isn't what I initially wanted but I figured I would at least document my findings if it helps future developers.

To enable CAN communication, I had to structure VESC packets in the format required to forward them. Once I figured out how to format them, the rest was choosing how to integrate that with the other ROS components.

My Technical Changes in Brief
In vesc_packet I created set methods to do the same thing as the existing non-CAN methods with the addition of packing can_id and command_id in the first two bytes followed by the original payload information and a CRC checksum. This was done by inheriting VescPacket with the COMM_FORWARD_CAN command id as specified in data_map.hpp. It would be cleaner if changes were made to existing methods instead of creating a set of new ones but I didn't have the time to explore that. The important thing was I needed to get the VESC packet to be in the required format for forwarding.

Example VESC packet.
[start] [length] [forward_command] [can_id] [command_to_forward] [data...] [CRC] [end]
[0x3] [0x07] [0x21] [0x0] [COMM_SET_DUTY] [data...] [CRC] [0x3]

Example code using VescPacket and new method VescPacketCANSetDuty. Notice the payload size argument is the original payload size plus two for the can_id and command_to_forward bytes.

VescPacketCANSetDuty::VescPacketCANSetDuty(double duty, uint8_t can_id) : VescPacket("CANSetDuty", 7, COMM_FORWARD_CAN)
{
  // Set up CAN forward packet structure
  *(payload_end_.first + 1) = can_id;
  *(payload_end_.first + 2) = COMM_SET_DUTY;

  // ...

  // Pack the duty value into the payload
  const int32_t v = static_cast<int32_t>(duty * 100000.0);
  *(payload_end_.first + 3) = static_cast<uint8_t>((v >> 24) & 0xFF);
  *(payload_end_.first + 4) = static_cast<uint8_t>((v >> 16) & 0xFF);
  *(payload_end_.first + 5) = static_cast<uint8_t>((v >> 8) & 0xFF);
  *(payload_end_.first + 6) = static_cast<uint8_t>(v & 0xFF);

  appendCRC();
}

start, end and length are handled by VescPacket.

I don't know if this kind of functionality is in the scope of this repository but I hope it helps others to understand VESC packet forwarding better.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants