we are integrating the Myxa in a “proof-of-concept-board” as we speak. I’d like to keep integration efforts low - at least until we know that everything works. So we’ll be using RCPWM to control the ESC and serial/UART interrogation to read out current, voltage, RPM, and possibly fault states.
We took a short look at the popcop documentation and figured that this requires some reading and some learning curve. So I was looking for an easier solution for reaching the “proof-of-concept”. So the question is: Do you have a code snippet for “this is what you send to interrogate” - and “this is how to decode the reply”?
It’s a tad complicated atm. We will be swapping out Popcop in favor of UAVCAN-over-serial in the release firmware, so Popcop (which was a testing ground for UAVCAN-over-serial) will reach its end-of-life soon.
Regardless, a simple Popcop usage example can be found in this script:
Thanks for the reply and the link to the example. In reading and cross-referencing it with the figure in GitHub - Zubax/popcop: OBSOLETE, use UAVCAN/serial instead, I still feel some unclarity on the exact number of bytes to send and expect back. I would really like to get our proof-of-concept-platform up and running without working my way through the popcop source code.
Therefore - and at the risk of seeming stupid and obnoxious - can I ask you to write the exact byte sequence of the empty GeneralStatusMessageV1 that triggers this response?
And could I ask you to “look over my shoulder” for a second? Can you verify and/or correct the following: I’ll expect the non-empty message to have the following sequence:
1 byte: 0x8E
8 bytes: timestamp
? bytes: status_flages
? bytes: current_task_id
3 bytes? padding
4 bytes: cpu temp
4 bytes: vsi temp
4 bytes: motor temp
4 bytes voltage
4 bytes current
4 bytes: pwm period
4 bytes: dead_time
4 bytes: upper_limit
4 bytes: lvps_malfunction
4 bytes: overload
4 bytes: fault
? bytes: task_specific_status_report
1 byte: 0x8E
And before parsing the string, it must be “cleaned” for the escape-character-replacement-thing?
Hi Max,
Any chance you got sorted with your problem. I am in the exact same position making a POC with MYXA and looking to get data on the serial port.
no I haven’t gotten further with that problem. But I did, indeed, smile a bit and enjoy reading your other post with your request. Knowing that there are more users with the same challenge might help in raising support priorities
But just out of curiosity: What kind of vehicle or project are you working on?
Apologies for the silence from our end. We are focused on the docs and finalization of the product so it’s a bit hard to keep track of the forum.
Most of our customers use UAVCAN or RCPWM (which are documented), your use case is slightly unconventional as of right now but as I said we’re working on the docs.
This should help for now (I have crafted this definition from the device-side protocol types; couldn’t validate it but I expect it to be correct):
struct GeneralStatusMessage
{
std::uint64_t timestamp_ns; ///< Nanosecond
std::uint64_t flags;
enum class TaskID : std::uint8_t
{
Idle,
Fault,
Beep,
Run,
HardwareTest,
MotorIdentification,
LowLevelManipulation
} current_task_id;
std::uint8_t explicit_padding_[3]{};
float cpu_temperature = 0; ///< Kelvin
float vsi_temperature = 0; ///< Kelvin
float motor_temperature = 0; ///< Kelvin
float dc_voltage = 0; ///< Volt
float dc_current = 0; ///< Volt
struct PWMState
{
float period = 0; ///< Second
float dead_time = 0; ///< Second
float upper_limit = 0; ///< Unitless, (0, 1]
} pwm_state;
struct OverflowingEdgeCounters ///< Number of activations per signal since boot up.
{
std::uint32_t lvps_malfunction = 0;
std::uint32_t overload = 0;
std::uint32_t fault = 0;
} hardware_flag_edge_counters;
// The content is defined by the current Task ID
std::array<std::uint8_t, 64> task_specific_structure{};
};
Same structure expressed using the Construct notation:
Task-specific status report for the Run task:
struct StatusReport
{
std::uint32_t stall_count;
float demand_factor_filtered;
float electrical_angvel_filtered;
float mechanical_angvel_filtered;
float torque_filtered;
float Udq_filtered[2];
float Idq_filtered[2];
enum class ControlMode : std::uint8_t
{
RatiometricCurrent, ///< Value in [-1, 1] that defines the current setpoint relative to the maximum
RatiometricAngVel, ///< Ditto, angular velocity setpoint relative to the maximum
RatiometricVoltage, ///< Ditto, voltage setpoint relative to the inverter supply voltage (Vbus)
Current, ///< Ampere
RPMM, ///< Mechanical RPM
Voltage ///< Voltage applied in the quadrature axis
} control_mode;
// Booleans are encoded like std::uint8_t
bool spinup_in_progress;
bool rotation_reversed;
bool controller_saturated;
};
Yes.
The timestamp is in nanoseconds, the rest is SI unless explicitly specified otherwise.
thanks. That helped clear up a few things. No problem with the delay. Keeping focus is a necessary part of getting things done. I’ve only got a few questions left on my sheet:
You state further above, in post #2, that triggering a status message is done by sending an empty status message to the controller. I am unsure about what is meant with “empty”. In the sense that all values are zero? Is the composition also “delimitier-payload-frametype-CRC-delimiter”?
I am only doing the whole popcop-serial thing as a means to validate that a Myxa works in our setup. If I understand you correctly, you’ll be releasing a new firmware with UAVCAN-over-serial in the near future. So depending on how soon this is, I might just hold off on the popcop thing and await the release. Can you give a hint about when this might be?
“Empty” means “without payload”; that is, “delimiter-frametype-CRC-delimiter”. Per the code I linked in my previous post, the frame type for the general status message is zero.
This is expected to arrive before the end of the year.
thanks a lot. I took some time this afternoon, dug out an old arduino and started feeding the Myxa’s serial interface - in order to get to the bottom of it and to understand what it does. But it still doesn’t talk back to me - although the Myxa is responding nicely to the RCPWM. So it does indeed start to get tedious. So please look over my shoulder once again.
What I did:
I found the files “xz_private.h” in the kucher folder and included it.
// Setup:
Serial3.begin(115200,SERIAL_8N1); // For the serial port
xz_crc32_init(); // Setting up the polynomial array
CRC = xz_crc32(&FrameType,1,0); //Calculating CRC for FrameType byte
The returned value of CRC is 0xD202EF8D. In main I call SendEmptyStatusMessage() which is:
But I don’t get any reply from the Myxa’s TX. That is, except for short bursts of data when starting and stopping the RCPWM. Thus, I know that I am measuring in the right place.
What/where am I doing something wrong? I’d really love a simple answer such as - for instance - just the contents of the CRC. Further links to GitHub is possibly going to overstretch my poor coding skills and patience.
Ah, it’s just an unrelated part of the application runtime rigging. You shouldn’t use it.
You are computing the CRC incorrectly; also, you do not seem to be escaping it. The correct CRC algorithm is CRC32C (Castagnoli), as stated in the Popcop description. Relevant sources:
Castagnoli has superior error detecting properties compared to the standard CRC32 (polynomial 0xedb88320).
You can dump the exchange between the device and Kucher to study it offline using this feature of the PySerial library: URL Handlers — pySerial 3.4 documentation. To use it, just replace the serial port name in Kucher with spy://<port-name>?file=dump.txt, for example:
Then click Connect and you’ll end up with a nice dump file: dump.txt (280.9 KB)
In the attached file you will see the initialization in the beginning, then the registers being read, and, near the end of the log, you will notice Kucher polling the general status message:
Hi Max, took me a while to get finally back at it.
I am working on a project for autonomous under-water vehicle.
I have on my others AUV some different kind of controler but thought this Myxa could make a real difference.
Still working on this serial connection. I am not familiar with python and got loss on the way.
What is your application ?
Celine