Repository navigation
cf.cmdVel(self, roll, pitch, yawrate, thrust) in sımulation (SIL) #832
Copy link
Copy link
Open
Description
We would like to implement our controller on a Crazyflie in simulation environment.
To do that, we need to use cmdVel method in crazyflie.py. However, we have realized that we need to fix a bunch of settings in crazyflie_server.py and crazyflie_sil.py in crazyflie_sim folder.
We have more or less fixed those code requirements. That being said, we have noticed that we should configure more settings to satisfy cffimware.py in crazyflie-firmware folder. That part have been harder than we have thought. I have attached the related codes below. Could you help us to be fixing this method for simulation?
cmdVel method in crazyflie.py:
...
self.cmdVelPublisher = node.create_publisher(Twist, prefix + '/cmd_vel_legacy', 1)
...
def cmdVel(self, roll, pitch, yawrate, thrust):
cmdVelMsg= Twist()
cmdVelMsg.linear.x = float(pitch)
cmdVelMsg.linear.y = float(roll)
cmdVelMsg.linear.z = float(thrust)
cmdVelMsg.angular.z = float(yawrate)
self.cmdVelPublisher.publish(cmdVelMsg)
settings in crazyflie_server.py:
def _cmd_vel_legacy_changed(self, msg, name=''):
"""
Translates Twist messages into Crazyflie setpoints.
msg.linear.x -> Pitch
msg.linear.y -> Roll
msg.angular.z -> Yaw Rate
msg.linear.z -> Thrust
"""
# 1. Extract values from the Twist message
roll = msg.linear.y
pitch = msg.linear.x
yaw_rate = msg.angular.z
thrust = int(max(0, min(65535, msg.linear.z))) # Usually needs to be a 16-bit integer
# 2. Send the setpoint via the Crazyflie Link
# Note: The specific API call depends on which library version you are using
#self.get_logger().info(f'Available methods: {dir(self.cfs[name])}')
try:
self.cfs[name].cmdVel(roll, pitch, yaw_rate, thrust)
except Exception as e:
self.get_logger().error(f'Failed to send setpoint: {e}')
settings in crazyflie_sil.py:
def cmdVel(self, roll, pitch, yaw_rate, thrust):
"""
Manually added to bridge the gap between SIL and physical API.
Maps legacy attitude commands to the simulation setpoint.
"""
# In SIL, 'self.setpoint' is likely the object used by the internal loop
firm.plan_stop(self.planner)
self.mode = CrazyflieSIL.MODE_LOW_FULLSTATE
self.setpoint.attitude.roll = float(roll)
self.setpoint.attitude.pitch = float(pitch)
self.setpoint.attitudeRate.yaw = float(yaw_rate)
self.setpoint.thrust = float(thrust)
self.cmdHl_yaw = np.radians(self.state.attitude.yaw)
self.cmdHl_pos = firm.mkvec(self.state.position.x,
self.state.position.y,
self.state.position.z)
# 2. Tell the firmware HOW to interpret these values
# modeAbs (2) means "Angle", modeRate (1) means "Angular Velocity"
self.setpoint.mode.roll = firm.modeAbs
self.setpoint.mode.pitch = firm.modeAbs
self.setpoint.mode.yaw = firm.modeVelocity
# 3. Disable coordinate-based positioning for manual flight
self.setpoint.mode.x = firm.modeDisable
self.setpoint.mode.y = firm.modeDisable
self.setpoint.mode.z = firm.modeDisable
# Crucial: Set the mode so the simulator knows to use these values
# Based on your dir() list, 'MODE_LOW_FULLSTATE' or similar might be needed
# But often, simply updating the setpoint object is enough for the next simulation tick.
our script to test cmdVel:
import rclpy
from crazyflie_py import Crazyswarm
def main():
swarm = Crazyswarm()
timeHelper = swarm.timeHelper
cf = swarm.allcfs.crazyflies[0]
#cf.cmdVel(roll=0.0, pitch=0.0, yawrate=0.0, thrust=0)
#cf.cmdVel(roll=0.0, pitch=0.0, yawrate=0.0, thrust=0)
print("Taking off...")
cf.takeoff(targetHeight=1.0, duration=2.0)
timeHelper.sleep(4.0)
print("Sending thrust...")
# Roll=20.0 degrees, Pitch=0, Yawrate=0, Thrust=42000
for _ in range(250): # 5 seconds at 50Hz
cf.cmdVel(roll=0.0, pitch=0.0, yawrate=0.0, thrust=48000)
timeHelper.sleepForRate(50)
print("Landing...")
cf.land(targetHeight=0.0, duration=2.0)
timeHelper.sleep(2.0)
if __name__ == "__main__":
main()
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
whoenig commentedon Apr 25, 2026
Could you describe what exactly is missing/not working in simulation?
ntukenmez3 commentedon Apr 25, 2026
We are currently not able to use
'/cmd_vel_legacy'to send roll, pitch, yaw rate and thrust in simulation.ntukenmez3 commentedon May 17, 2026
Can we get any help with this? Thank you in advance.
whoenig commentedon May 18, 2026
The code you posted seems to be an attempt to implement this missing functionality, but is not working - correct?
ntukenmez3 commentedon May 18, 2026
Precisely, we wanted to make this functionality, i.e.,
cf.cmdVel(roll=..., pitch=..., yawrate=..., thrust=...).ntukenmez3 commentedon Jun 16, 2026
is that possible to activate this functionality?
whoenig commentedon Jun 16, 2026
You already posted some code in the initial issue. Could you describe more clearly what happens (or not happens) when you use your code in your simulation? In other words, given that you have already implemented the feature at least partially, what is it that you are missing?