added motor-plugin and DroneCAN ESC telemetry script - #146
added motor-plugin and DroneCAN ESC telemetry script#146Bhajneet-Singh-Bedi wants to merge 3 commits into
Conversation
| /* | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| * | ||
| */ |
There was a problem hiding this comment.
Should be LGPLv3. The original ArduPilotPlugin code was Apache, but new works should match the repo license (https://github.com/ArduPilot/ardupilot_gazebo/blob/main/LICENSE.md). See https://github.com/ArduPilot/ardupilot_gazebo/blob/main/include/SocketUDP.hh for example text to include in source files.
| inline namespace GZ_SIM_VERSION_NAMESPACE { | ||
| namespace systems { | ||
|
|
||
|
|
There was a problem hiding this comment.
Include a doc string describing the plugins purpose and SDF parameters. See for example: https://github.com/ArduPilot/ardupilot_gazebo/blob/main/include/GstCameraPlugin.hh
| /// \brief Load control channels | ||
| private: void LoadControlChannels( | ||
| sdf::ElementPtr _sdf, | ||
| gz::sim::EntityComponentManager &_ecm); |
There was a problem hiding this comment.
Can be in the private Impl class as this function is not called by the Gazebo system.
| /* | ||
| Copyright (C) 2025 ArduPilot.org |
There was a problem hiding this comment.
Use this license text in MotorPlugin.hh as well.
| public: double speedConstant; | ||
|
|
||
| /// \brief motor internal resistance | ||
| public: double internal_resistance; |
There was a problem hiding this comment.
| public: double internal_resistance; | |
| public: double internalResistance; |
| public: double offset; | ||
|
|
||
| /// \brief thermal resistance of the motor | ||
| public: double thermal_resistance; |
There was a problem hiding this comment.
| public: double thermal_resistance; | |
| public: double thermalResistance; |
| public: double thermal_resistance; | ||
|
|
||
| /// \brief thermal capacitance of the motor | ||
| public: double thermal_capacitance; |
There was a problem hiding this comment.
| public: double thermal_capacitance; | |
| public: double thermalCapacitance; |
| public: double thermal_capacitance; | ||
|
|
||
| /// \brief ambient working temperature | ||
| public: double ambient_temperature; |
There was a problem hiding this comment.
| public: double ambient_temperature; | |
| public: double ambientTemperature; |
| /// \param controlIndex -> Index of the message | ||
| /// \param _msg -> message itself. | ||
| /// The command message is a target Velocity. | ||
| public: void OnVelMsg(int controlIndex, const gz::msgs::Double &_msg); |
There was a problem hiding this comment.
| public: void OnVelMsg(int controlIndex, const gz::msgs::Double &_msg); | |
| public: void OnVelMsg(int _controlIndex, const gz::msgs::Double &_msg); |
| }; | ||
|
|
||
| ////////////////////////////////////////////////// | ||
| void MotorPlugin::Impl::OnVelMsg(int controlIndex, const gz::msgs::Double &_msg) |
There was a problem hiding this comment.
| void MotorPlugin::Impl::OnVelMsg(int controlIndex, const gz::msgs::Double &_msg) | |
| void MotorPlugin::Impl::OnVelMsg(int _controlIndex, const gz::msgs::Double &_msg) |
| } | ||
|
|
||
| ///////////////////////////////////////////////// | ||
| void MotorPlugin::LoadControlChannels( |
There was a problem hiding this comment.
| void MotorPlugin::LoadControlChannels( | |
| void MotorPlugin::Impl::LoadControlChannels( |
And move declaration from MotorPlugin.hh.
| @@ -215,14 +215,15 @@ | |||
| <offset>0</offset> | |||
There was a problem hiding this comment.
I'd prefer to see the changes to the models split into a separate PR. That way we can proceed with including the motor plugin without altering the existing models and their behaviour. When we're more comfortable with the plugin we can consider migrating the examples over to it.
In the meanwhile a small test model (one of the iris motors and prop fixed to a thrust stand would be good). That would allow testing and demonstrations. It could even have a force torque sensor plugin included in the joint for additional feedback.
| // Current drawn by the motor in Amperes. | ||
| double current = 4; | ||
|
|
||
| // Motor Temperature in Celsius. |
There was a problem hiding this comment.
Temperature in Kelvin.
| package ardupilot_gazebo.msgs; | ||
|
|
||
| // Message to hold the status of a single motor. | ||
| message MotorStats { |
There was a problem hiding this comment.
| message MotorStats { | |
| message MotorStatus { |
MotorStatus better aligns with the DroneCAN message names (uavcan.equipment.esc.Status and uavcan.equipment.esc.StatusExtended). See for example: https://github.com/dronecan/DSDL/blob/master/uavcan/equipment/esc/1034.Status.uavcan
| # Basic setup for dronecan:- | ||
| # sudo modprobe vcan | ||
| # sudo ip link add dev vcan0 type vcan | ||
| # sudo ip link set up vcan0 | ||
| # To check:- ip link show vcan0 |
There was a problem hiding this comment.
We should be able to run this without needing to use sudo?
For example:
- https://github.com/srmainwaring/ardupilot_gazebo-1/blob/wips/wip-dronecan/scripts/dronecan_sensor.py
(that script following the examples in the dronecan repo and tutorials)
|
|
||
| GZ_ADD_PLUGIN_ALIAS( | ||
| gz::sim::systems::MotorPlugin, | ||
| "MotorPlugin") No newline at end of file |
There was a problem hiding this comment.
Add blank line at end.
| /// \brief Array of msg command topics. | ||
| public: std::vector<std::string> topics; | ||
|
|
||
| /// \brief Stores target velocity values. |
There was a problem hiding this comment.
I was not expecting to see a target velocity here. My understanding of how the motor model would work after reviewing the JSBSim implementation (https://github.com/JSBSim-Team/jsbsim/blob/b005a91d3151624eb26ae5595570bd188ef49702/src/models/propulsion/FGBrushLessDCMotor.cpp) using the same paper http://web.mit.edu/drela/Public/web/qprop/motor1_theory.pdf, is that the input to the model is a throttle with range [0, 1].
The input pwm [1000, 2000] scaled with multiplier 1 and offset 0 would provide the mapping.
The maximum power output is then determined by the max battery voltage (throttle = 1), and the subsequent motor velocity a result of the prop details and motor Kv and friction etc. This was summarised here: https://discord.com/channels/@me/1376945277940011098/1406220672027590696
c3ded1c to
db542c8
Compare
…ded motor_model.sdf, corrected temperature units
db542c8 to
d7b7960
Compare
Description
This PR introduces a gazebo plugin of an electro-mechanical model of a motor. This plugin enhances the motor control in a model.
Details
How to use this plugin?
Include this in the sdf file:-
You can keep adding more channels and sub parameters based on number of motors.
The parameters of the above given example motor are taken from AIR 2216 920KVmotor's datasheet which is being used in iris quadcopter.
For calculating thermal parameters:-
This PR includes a model_model.sdf in worlds/ folder which includes this plugin. When you run that using
gz sim -v4 -r motor_model.sdfgz topic -t /joint_0_topic -m gz.msgs.Double -p 'data: 0.3You will see a "/model/motor_model_demo/joint/joint_0/motor_stats" topic being published for that joint.
To see the logs of the topics, go to build directory in ardupilot_gazebo/ workspace and run:
export GZ_DESCRIPTOR_PATH=`pwdThis will set the GZ_DESCRIPTOR_PATH and you'll be able to see the output in terminal.
To run the python script which subscribes to these motor stats topic and publishes DroneCAN ESC type telemetry data. First run this:
export PYTHONPATH=$PYTHONPATH:`pwd`/build/ardupilot_gazebo-msgs_genmsg/python/in ardupilot_gazebo/ workspace.python3 scripts/motor_status.pyfrom the same ardupilot_gazebo/ workspace.Future works