I am trying to write my own HIL code that makes use of the MAVLINK protocol and a Pixhawk autopilot. I'll try to explain what I'm trying to do before I go into the problems I am having:
The overall architecture of my system is I want to use an actual Pixhawk to command motions in a simulated environment (in this case it is a ROS/Gazebo environment) and then have the simulated environment provide inputs back to the Pixhawk controller to subsequently update the motor commands (and so on...the loop continues). I will be getting waypoints from an external source to actually guide the motion, but that is neither here nor there at this point.
I have my simulation environment set up and sending a HIL_STATE MAVLINK message (this will be changed to the HIL_STATE_QUATERNION message in the near future) which should then be picked up by the Pixhawk and the controller should update motor/servo commands accordingly. The problem I am having is two-fold:
1) I can't seem to get the Pixhawk into HIL mode. I know there is a MAVLINK message "SET_MODE" but it doesn't seem to be working properly. (see https://pixhawk.ethz.ch/mavlink/ for the MAVLINK common messages)
2) I can't seem to find any messages that would dictate motor commands, either PWM or RPM directly.
So my questions are: 1) Does anyone know how to set the Pixhawk into HIL programmatically (i.e. without Mission Planner or other GCS software)? and 2) Does anyone have any insight into how I can get the controller output from the Pixhawk (i.e. the motor commands)?
Any help would be greatly appreciated, thank you!
P.S. I am doing this with a simulated quadrotor, but the same process will most likely be applied to a fixed wing as well, so either ArduCopter or ArduPlane suggestions would be helpful.
Using the APM software on the Pixhawk:
1) Setting the HIL_MODE parameter to 1 will enable HIL mode on the next reboot. You will need GCS software to make this initial change. The APM will stay in HIL mode thereafter (unless HIL_MODE is set back to 0 and rebooted). See http://plane.ardupilot.com/wiki/arduplane-parameters/#hil_mode_enab...
2) The RC_CHANNELS_SCALED Mavlink message contains the motor (and any other servo) PWM values. See https://pixhawk.ethz.ch/mavlink/#RC_CHANNELS_SCALED
Stephen, thank you for the quick reply. I was looking at the RC_CHANNELS_SCALED message, but that doesn't seem to be the output from the Pixhawk. Am I misunderstanding the MAVLINK message specification for that message? I am looking for a message that contains what the Pixhawk sends to the motors (i.e. PWM or RPM directly) so I can directly control the motors in my simulation.
If the RC_CHANNELS_SCALED is that message, then great! It just doesn't seem like that's what I'm looking for based on the way I read the message specification.
Ahh, I see what you mean. I should have been more specific!
RC_CHANNELS_SCALED is a "read-only" message showing what PWM values the APM is outputting. You are correct in that it's what values are sent to the servos or ESC's.
If you want to send RC values to the APM (ie. what the RC Transmitter sends), there should be a packet to do that, but I can't seem to find it. I'd recommend looking through the pymavlink code and see if there's any examples there.
Stephen, the message I really needed was actually the SERVO_OUTPUT_RAW message, and I got that working for my purposes. So right now, I have the servo outputs from the Pixhawk being mapped to RPM and subsequently being sent into the Gazebo/ROS environment, which then drives the simulated motors. The missing piece is still setting the Pixhawk into HIL mode.
Unfortunately, I can't seem to find a way to put the Pixhawk into HIL mode programmatically. Is this even possible? I know you mentioned that I should use the APM software, but I need this system to be standalone. There has to be a way to set the Pixhawk into HIL mode via a MAVLINK message because the APM software does so (somehow....can't seem to find it anywhere).
My initial thought was the SET_MODE message (#11) and setting the base or custom mode, but this doesn't seem to be working. Any insights? Thanks again for all the help!
Ahh, my mistake! SERVO_OUTPUT_RAW is indeed what you need for reading the PWM outputs.
I'm not too sure I understand you in regard to HIL mode. Are you using the PX4 Flight software or APM flight software on the Pixhawk? (https://pixhawk.org/choice).
The Pixhawk is just the physical hardware (running the Nuttx operating system). There's no "default" or underlying flight controller on it. Much like a phone or PC you need to install the PX4 or APM flight software onto the Pixhawk to make it work as a flight controller.
I've re-read your message. There is a Mavlink message to set a parameter: MAV_CMD with the MAV_CMD_DO_SET_PARAMETER command. This is what any GCS software (Mission Planner, MAVProxy, etc) uses to set parameters on the APM.
So I saw the MAV_CMD and MAV_CMD_DO_SET_PARAMETER, but it doesn't look like MAV_CMD is a message. I can't seem to figure out how to send that, but I'll keep looking because that seems to be exactly what I want.
And to further explain what I mean when I say HIL mode, I'll try to outline my architecture:
--An external software will supply the Pixhawk (and associated software) with waypoints, similar to how APM Mission Planner supplies waypoints.
--Then, the Pixhawk compares its current state (supplied by the simulation environment, which I'll describe later) to the waypoint to produce control inputs for the motors.
--I grab those inputs from the SERVO_OUTPUT_RAW message we discussed earlier and then send that command into a Gazebo/ROS simulated environment.
--Once in the simulated environment, the simulated quadrotor responds to the motor commands and subsequently provides IMU and other sensor data.
--I take the relevant sensor data and pack it into the HIL_STATE MAVLINK message (which will be replaced by the HIL_STATE_QUATERNION message soon). The HIL_STATE message is what is compared to the waypoint received, which I mentioned earlier.
Basically, I need the Pixhawk software to respond to simulated sensor and state information instead of actual sensor/state information, if that makes sense.
So the trouble I am having is I think I need to get the Pixhawk into HIL mode in order to accept the HIL_STATE message. I can't figure out quite how to get the Pixhawk into HIL mode, or if there is a workaround that will allow me to feed in simulated sensor data to override the actual IMU (and other sensor) data and have the controller act on that data instead.
Stephen, I think I figured out what you meant by your previous message. Using the MISSION_ITEM message (#39), you can send a MAV_CMD value and that is how I would set the Pixhawk into HIL mode.
Now my problem is actually getting an ACK back from the Pixhawk after I send it a MISSION_ITEM message. I've even tried sending waypoints by first sending a MISSION_WRITE_PARTIAL_LIST message, then listening for a MISSION_COUNT message in return, but no luck.
Any idea what messages I should actually be listening for in return/acknowledgment for setting the mode and/or sending a waypoint to the Pixhawk?
I started a new topic because I made significant changes to what I have done so far, and I feel like it required a more clear description. It can be found here: http://diydrones.com/forum/topics/custom-hil-program-with-ros-gazeb....
I don't know how to merge topics, but if you do could you let me know so I can merge these two? Otherwise, I may just close this one... Thanks again for all your help!
I am using the Arduplane 3.4.0 build loaded on the Pixhawk. I have set the HIL_MODE to 1. However I am not able to retrieve any servo outputs except servo channel 2 showing up as 1500.
I am using MSG_ID RC_CHANNELS_OVERRIDE to set the PWM commands mimicking an RC Input. I have armed the board and put the MODE to AUTO (92). After setting the throttle to 255 and ROLL Channel to 255 I am writing the serial packet. Thereafter I am querying the PX4 for 2000ms looking for packet MAVLink.mavlink_servo_output_raw_t but I am getting only Channel 2 i.e. Pitch channel as 1500. This is persistent no matter whatever I change in RC_CHANNELS_OVERRIDE members.
Can somebody help?