-
Notifications
You must be signed in to change notification settings - Fork 0
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
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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.
-
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 thetest
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. -
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.
-
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).
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> |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#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); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
// 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(); |
There was a problem hiding this comment.
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
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; | ||
} |
There was a problem hiding this comment.
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
?
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; | |
} | |
// motorTrLeft.stop(); | ||
// motorTrRight.stop(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above
/* | ||
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> |
There was a problem hiding this comment.
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
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; }); |
No description provided.