-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathCrazyflieController.cs
115 lines (102 loc) · 3.99 KB
/
CrazyflieController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System.Threading;
using System.Threading.Tasks;
namespace CrazyflieClient
{
//
// Summary:
// This class implements the control of
// a crazyflie 2.0 quadcopter via BLE
//
// Uses an object which implements the IFlightController
// interface for determining flight commander setpoints
class CrazyflieController
{
private IFlightController flightController;
private CancellationTokenSource cancellationSource;
private BthCrtp bthCrtp;
private const int MaxThrust = 65536;
//
// Summary:
// Maximum pitch/roll value to send to the commander, in degrees
private double maxPitchRollRate = 30;
public double MaxPitchRollRate
{
get { return maxPitchRollRate; }
set { maxPitchRollRate = value; }
}
//
// Summary:
// Maximum yaw value to send to the commander, in degrees
private double maxYawRate = 200; // degrees per second
public double MaxYawRate
{
get { return maxYawRate; }
set { maxYawRate = value; }
}
//
// Summary:
// Maximum roll value to send to the commander, in percent (0 to 1)
private double maxThrustPercent = 0.8;
public double MaxThrustPercent
{
get { return maxThrustPercent; }
set { maxThrustPercent = value; }
}
public CrazyflieController(IFlightController flightController)
{
this.flightController = flightController;
bthCrtp = new BthCrtp();
}
public async Task<bool> IsCrazyfliePaired()
{
return await bthCrtp.IsCrazyfliePaired();
}
//
// Summary:
// This function starts the communication to the crazyflie commander
// to set flight setpoints based on the state of the flight controller
public async void StartCommanderLink()
{
// Set up the cancellation token
if (cancellationSource != null)
{
cancellationSource.Dispose();
}
await bthCrtp.InitCrtpService();
cancellationSource = new CancellationTokenSource();
Task t = Task.Factory.StartNew(() => CommanderSetpointThread(cancellationSource.Token), TaskCreationOptions.LongRunning);
}
//
// Summary:
// This function stops the communication to the crazyflie commander
public void StopCommanderLink()
{
if (cancellationSource != null)
{
// TODO: consider writing zeros here to shut motors off
// Not critical, as the commander code in the CF FW will time out
cancellationSource.Cancel();
}
}
//
// Summary:
// Thread function for writing commander packets via BTH
// Writes as fast as it can in a tight loop
private async void CommanderSetpointThread(CancellationToken cancellationToken)
{
// Write commander packets as fast as possible in a loop until cancelled
while(!cancellationToken.IsCancellationRequested)
{
FlightControlAxes axes = await flightController.GetFlightControlAxes();
// Use the emulated CPPM commander type to allow arming in Betaflight
await bthCrtp.WriteCppmCommanderPacket(
(ushort)((axes.roll * 500) + 1500),
(ushort)((axes.pitch * 500) + 1500),
(ushort)((axes.yaw * 500) + 1500),
(ushort)((axes.thrust * 1000 * maxThrustPercent) + 1000),
(ushort)(axes.isSelfLevelEnabled ? 2000 : 1000),
(ushort)(axes.isArmed ? 2000 : 1000));
}
}
}
}