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 library and .ino test code upload #5

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

CAN library and .ino test code upload #5

wants to merge 1 commit into from

Conversation

m4r14g
Copy link

@m4r14g m4r14g commented Dec 27, 2024

No description provided.

@m4r14g m4r14g requested a review from luca-byte December 27, 2024 22:33
Copy link
Member

@luca-byte luca-byte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job 🎯

As we saw in the meeting the code is working, which is the most important thing.

I would like to just leave some generic comments regarding the next steps and the needed improvements.

  1. At the moment this library (in my opinion) is not ready to go into the source code (src) because is using many magic numbers instead of using the "final approach". As I see it we can either 1. put this in the test folder or 2. restructure it as if the other libraries are already present. Both this options have their pros and cons, but in any case I would gladly listen to your input on the matter.

  2. Moreover the code has many stylistic problems (multiple blank lines, unaligned braces,...), which in codebases can be problematic, so I would suggest you to run your code through a formatter. If you have any questions about it, ask me.

  3. In the end I noticed that the code uses slightly different approaches each time it does something similar, which impacts negatively the readability (for example the feedback value sometimes is obtained before setting up the CAN address, sometimes after).

⚠️ Consider that these are very small issues but it is the work of the reviewers to point these out to obtain a as-good-as-possible codebase. I really consider this to be a very good approach to obtain a working CAN interface and the testing-driven development is something very positive. I suggest you to work on points 2 and 3 while we can also discuss about the approach for point 1.

Obviously, feel free to reach out if you need anything or if something is not clear.

@@ -0,0 +1,196 @@
#include "CAN.h"

#include <cstring>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is not needed. Could you please verify it?


#include <cstring>

#define CAN_ID 0x11 // this shouldn't be here in the end but specified in the makefile
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define CAN_ID 0x11 // this shouldn't be here in the end but specified in the makefile

As you noted this should not be here. As for tests you can define temporarily #define MOD_HEAD in mod_config.h but this should not be pushed to production

// I
void CAN::init() {
// configure CAN
CAN0.setCANPins((gpio_num_t)36, (gpio_num_t)35);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PINs can go to the definition file IMHO

void CAN::init() {
// configure CAN
CAN0.setCANPins((gpio_num_t)36, (gpio_num_t)35);
CAN0.begin(125000);
Copy link
Member

@luca-byte luca-byte Dec 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (the bitrate) can be a parameter in the CAN.h class

// configure CAN
CAN0.setCANPins((gpio_num_t)36, (gpio_num_t)35);
CAN0.begin(125000);
CAN0.watchFor(); // use this to filter for specific IDs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: at the moment the CAN is not filtering messages? If this is the case, it is problematic because it could enact on commands meant for other modules

bool CAN::receiveMotorSetpoint() {
// take the first four bytes from the array and and put them in a float
float leftSpeed, rightSpeed;
memcpy(&leftSpeed, canMsg.data.uint8, 4); // Copia i primi 4 byte per leftSpeed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments should be in english

Comment on lines +156 to +167
// DEBUG: print frame
Serial.println("I'm receiving...");
Serial.print(canMsg.id, HEX);
if (canMsg.extended) {
Serial.print(" X ");}
else {
Serial.print(" S "); }
Serial.print(canMsg.length, DEC);
for (int i = 0; i < canMsg.length; i++) {
Serial.print(canMsg.data.byte[i], HEX);
Serial.print(" ");}
Serial.println();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will go to the Debug class, but is ok

Comment on lines +170 to +183
if (type == MOTOR_SETPOINT_ID) {
receiveMotorSetpoint();
}
else if (type == END_EFFECTOR_PITCH_SETPOINT_ID ||
type == END_EFFECTOR_HEAD_PITCH_SETPOINT_ID ||
type == END_EFFECTOR_HEAD_ROLL_SETPOINT_ID) {
receiveEndEffectorSetpoint(type);
}
else if (type == JOINT_YAW_SETPOINT_ID) {
receiveJointSetpoint();
}

return true;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about a switch-case?

Suggested change
if (type == MOTOR_SETPOINT_ID) {
receiveMotorSetpoint();
}
else if (type == END_EFFECTOR_PITCH_SETPOINT_ID ||
type == END_EFFECTOR_HEAD_PITCH_SETPOINT_ID ||
type == END_EFFECTOR_HEAD_ROLL_SETPOINT_ID) {
receiveEndEffectorSetpoint(type);
}
else if (type == JOINT_YAW_SETPOINT_ID) {
receiveJointSetpoint();
}
return true;
}
switch (type) {
case MOTOR_SETPOINT_ID:
receiveMotorSetpoint();
break;
case END_EFFECTOR_PITCH_SETPOINT_ID:
case END_EFFECTOR_HEAD_PITCH_SETPOINT_ID:
case END_EFFECTOR_HEAD_ROLL_SETPOINT_ID:
receiveEndEffectorSetpoint(type);
break;
case JOINT_YAW_SETPOINT_ID:
receiveJointSetpoint();
break;
}
return true;
}

Comment on lines +191 to +192
// motorTrLeft.stop();
// motorTrRight.stop();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

Comment on lines +1 to +8
/*
Using https://github.com/collin80/esp32_can
which requires https://github.com/collin80/can_common
Install both by downloading the ZIP file from GitHub.

*/

#include <esp32_can.h>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these are file we need to copy (not installable using the Arduino IDE) I think that we can copy them directly in the codebase in this folder

@luca-byte
Copy link
Member

About the discussion (1.), I realized that there is also another option which I believe to be cleaner and which would make the CAN code agnostic w.r.t. the sensor implementation and methods, using lambda functions. Essentially the methods which provide feedbacks and which receive setpoints will have as parameters a lambda function which will be called and provides the implementation

An example for the joint feedback follows:

#include <functional>

class CAN {
public:
    void sendJointFeedback(std::function<float()> getAngle);
    // altre funzioni e membri...
};

void CAN::sendJointFeedback(std::function<float()> getAngle) {
    float angle = getAngle();
    canMsg.id = 0; 
    canMsg.id = CAN_ID | (JOINT_YAW_FEEDBACK_ID << 16);     
    canMsg.length = 4;  
    canMsg.rtr = 0;    
    canMsg.extended = 1; 
    memcpy(canMsg.data.uint32, &angle, 4);
    CAN0.sendFrame(canMsg);
}

// Esempio di utilizzo
AbsoluteEncoder encoderYaw;
CAN can;

can.sendJointFeedback([&encoderYaw]() { return encoderYaw.readAngle(); });

If you are interested in considering this approach, it can be tested by passing a constant function

can.sendJointFeedback([]() { return 5.0f; });

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

Successfully merging this pull request may close these issues.

2 participants