Hi,
I'm trying to use UgCS .NET SDK to control my DJI Phantom 3 Pro. I wanted to start with the most basic functionality - arm/disarm. I am able to connect to the UgCS server, get the list of vehicles and select the P3P, but then when I send the Arm command it returns immediately with no effect.
Bellow is the code, I'm sure I'm missing something but I can't find out what. Any help is welcome,
Thank,
Nir.
------------------------------------
using System;using System.Collections.Generic;using System.Linq;using System.Text;
using System.Threading.Tasks;
using UGCS.Sdk.Protocol;
using UGCS.Sdk.Protocol.Encoding;
using UGCS.Sdk.Tasks;
using ProtoBuf;
namespace ArmTest
{
class Program
{
static void Main(string[] args)
{
/* Connects to UgCS server */
TcpClient tcpClient = new TcpClient("localhost", 3334);
MessageSender messageSender = new MessageSender(tcpClient.Session);
MessageReceiver messageReceiver = new MessageReceiver(tcpClient.Session);
MessageExecutor messageExecutor = new MessageExecutor(messageSender, messageReceiver, new InstantTaskScheduler());
messageExecutor.Configuration.DefaultTimeout = 10000;
var notificationListener = new NotificationListener();
messageReceiver.AddListener(-1, notificationListener);
/* Gets client ID */
AuthorizeHciRequest AuthRequest = new AuthorizeHciRequest();
AuthRequest.ClientId = -1;
AuthRequest.Locale = "en-US";
var future = messageExecutor.Submit(AuthRequest);
future.Wait();
AuthorizeHciResponse AuthorizeHciResponse = future.Value;
int clientId = AuthorizeHciResponse.ClientId;
/* Logs into the server */
LoginRequest loginRequest = new LoginRequest();
loginRequest.UserLogin = "admin";
loginRequest.UserPassword = "admin";
loginRequest.ClientId = clientId;
var loginResponcetask = messageExecutor.Submit(loginRequest);
loginResponcetask.Wait();
/* Gets list of vehicles */
GetObjectListRequest getObjectListRequest = new GetObjectListRequest()
{
ClientId = clientId,
ObjectType = "Vehicle",
RefreshDependencies = true
};
getObjectListRequest.RefreshExcludes.Add("Avatar");
getObjectListRequest.RefreshExcludes.Add("PayloadProfile");
getObjectListRequest.RefreshExcludes.Add("Route");
var task = messageExecutor.Submit(getObjectListRequest);
task.Wait();
/* Outputs found vehivles */
var list = task.Value;
foreach (var v in list.Objects)
{
System.Console.WriteLine(string.Format("Idx: {0}; name: {1}; id: {2}; type: {3}",
list.Objects.IndexOf(v), v.Vehicle.Name, v.Vehicle.Id, v.Vehicle.Type.ToString()));
}
System.Console.Write(string.Format("Select Vehicle Idx: "));
var userSelectedId = Console.Read();
/* Sets vehicle */
Vehicle vehicle = task.Value.Objects.FirstOrDefault().Vehicle;
vehicle.Id = userSelectedId;
/* Sends ARM command */
SendCommandRequest CmdRequest = new SendCommandRequest
{
ClientId = clientId,
Command = new UGCS.Sdk.Protocol.Encoding.Command
{
Code = "arm",
Subsystem = Subsystem.S_FLIGHT_CONTROLLER,
}
};
CmdRequest.Vehicles.Add(new Vehicle() { Id = vehicle.Id });
var CmdResponce = messageExecutor.Submit(CmdRequest);
CmdResponce.Wait();
System.Threading.Thread.Sleep(5000);
/* Sends DISARM command */
CmdRequest.Command = new UGCS.Sdk.Protocol.Encoding.Command
{
Code = "disarm",
Subsystem = Subsystem.S_FLIGHT_CONTROLLER,
};
CmdRequest.Vehicles.Add(new Vehicle() { Id = vehicle.Id });
CmdResponce = messageExecutor.Submit(CmdRequest);
CmdResponce.Wait();
/* Clean ups */
tcpClient.Close();
messageSender.Cancel();
messageReceiver.Cancel();
messageExecutor.Close();
notificationListener.Dispose();
}
}
}
------------------------------------
Replies
Dear Nir,
Could you send me the full log and new your programme?
Best regards,
Sergey Zuev
www.ugcs.com/support
Some more information:
After trying many different commands and failing with the same error ("Action requires exclusive vehicle control") I managed to get a different response when submitting "AcquireLockRequest". Now I'm getting the following error for the arm command:
2017-07-11 17:00:26,269 INFO [NioProcessor-3] com.ugcs.messaging.mina.MinaAdapter - Session 25 opened {local: /127.0.0.1:3334, remote: /127.0.0.1:60399}
2017-07-11 17:00:26,769 DEBUG [pool-9-thread-2] com.ugcs.ucs.service.VehicleRadarService - Radar enabled for the vehicle [Phantom3-COPTER-70null].
2017-07-11 17:00:26,769 DEBUG [pool-9-thread-2] com.ugcs.ucs.service.impl.LockServiceImpl - Vehicle:3 lock acquired by <User> admin
2017-07-11 17:00:26,808 WARN [pool-9-thread-2] com.ugcs.ucs.service.command.CommandServiceImpl - Cannot send command
com.ugcs.ucs.service.UcsException: Command not registered: <cmd> arm @ FLIGHT_CONTROLLER#0.
What does it mean to register a command? how do I do it?
Hi Again,
I started checking the UgCS logs, and seem to have found an issue (which I can't understand) in ucs.log.
The issue is the same both when using vehicle_id or the vehicle object. To create minimal log, this is the log starting when my C# code starts.
I see the line: "com.ugcs.ucs.service.UcsException: Action requires exclusive vehicle control." but I do not understand it's meaning.
Here is the full log:
2017-07-11 15:24:29,640 INFO [NioProcessor-2] com.ugcs.messaging.mina.MinaAdapter - Session 8 opened {local: /127.0.0.1:3334, remote: /127.0.0.1:64349}
2017-07-11 15:24:29,640 INFO [pool-9-thread-1] com.ugcs.messaging.GroupingThreadPool - W-pool-9-thread-1 START
2017-07-11 15:24:29,827 INFO [pool-9-thread-1] com.ugcs.ucs.service.impl.LicenseServiceImpl - License permissions cache updated
2017-07-11 15:24:29,828 INFO [pool-9-thread-1] com.ugcs.ucs.service.impl.LicenseServiceImpl - Max HCI sessions: 1
Multinode deployment enabled: false
KML import enabled: false
DEM import enabled: false
Group operations enabled: false
Max images to process: 20
Max AGL altitude:
[default] -> 120.0
Emulator -> 1.7976931348623157E308
Max distance to home:
[default] -> 500.0
Emulator -> 1.7976931348623157E308
Max buildings:
[default] -> 20
Emulator -> 2147483647
Custom NFZ enabled:
[default] -> false
Emulator -> true
Airport NFZ can be disabled:
[default] -> false
Emulator -> true
ADS-B receiver features enabled:
[default] -> false
Emulator -> true
ADS-B transponder features enabled:
[default] -> false
Emulator -> false
Video recording enabled:
[default] -> false
Emulator -> true
Camera footprint enabled:
[default] -> false
Emulator -> true
Forbidden algorithm codes:
[photogrammetry]
2017-07-11 15:24:30,420 DEBUG [pool-9-thread-1] com.ugcs.ucs.service.impl.LockServiceImpl - Trying to create entity lock map for Vehicle.
2017-07-11 15:24:30,420 DEBUG [pool-9-thread-1] com.ugcs.ucs.service.impl.LockServiceImpl - Entity lock map created for Vehicle.
2017-07-11 15:24:30,420 WARN [pool-9-thread-1] com.ugcs.ucs.service.command.CommandServiceImpl - Cannot send command
com.ugcs.ucs.service.UcsException: Action requires exclusive vehicle control.
at com.ugcs.ucs.service.command.CommandServiceImpl.sendCommandImpl(CommandServiceImpl.java:279)
at com.ugcs.ucs.service.command.CommandServiceImpl.sendCommand(CommandServiceImpl.java:208)
at com.ugcs.ucs.hci.handler.SendCommandHandler.process(SendCommandHandler.java:35)
at com.ugcs.ucs.hci.HciMessageListener.handleRequest(HciMessageListener.java:94)
at com.ugcs.ucs.hci.HciMessageListener.messageReceived(HciMessageListener.java:48)
at com.ugcs.messaging.mina.MinaMessageSession.messageReceived(MinaMessageSession.java:156)
at com.ugcs.messaging.mina.MinaAdapter.messageReceived(MinaAdapter.java:99)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:854)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:943)
at org.apache.mina.filter.logging.LoggingFilter.messageReceived(LoggingFilter.java:208)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:943)
at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:74)
at org.apache.mina.core.session.IoEvent.run(IoEvent.java:63)
at com.ugcs.messaging.GroupingThreadPool$Worker.run(GroupingThreadPool.java:519)
at java.lang.Thread.run(Unknown Source)
2017-07-11 15:24:35,462 WARN [pool-9-thread-1] com.ugcs.ucs.service.command.CommandServiceImpl - Cannot send command
com.ugcs.ucs.service.UcsException: Action requires exclusive vehicle control.
at com.ugcs.ucs.service.command.CommandServiceImpl.sendCommandImpl(CommandServiceImpl.java:279)
at com.ugcs.ucs.service.command.CommandServiceImpl.sendCommand(CommandServiceImpl.java:208)
at com.ugcs.ucs.hci.handler.SendCommandHandler.process(SendCommandHandler.java:35)
at com.ugcs.ucs.hci.HciMessageListener.handleRequest(HciMessageListener.java:94)
at com.ugcs.ucs.hci.HciMessageListener.messageReceived(HciMessageListener.java:48)
at com.ugcs.messaging.mina.MinaMessageSession.messageReceived(MinaMessageSession.java:156)
at com.ugcs.messaging.mina.MinaAdapter.messageReceived(MinaAdapter.java:99)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceived(DefaultIoFilterChain.java:854)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:943)
at org.apache.mina.filter.logging.LoggingFilter.messageReceived(LoggingFilter.java:208)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(DefaultIoFilterChain.java:542)
at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:48)
at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceived(DefaultIoFilterChain.java:943)
at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:74)
at org.apache.mina.core.session.IoEvent.run(IoEvent.java:63)
at com.ugcs.messaging.GroupingThreadPool$Worker.run(GroupingThreadPool.java:519)
at java.lang.Thread.run(Unknown Source)
2017-07-11 15:24:35,475 INFO [pool-9-thread-1] com.ugcs.messaging.mina.MinaAdapter - Session 8 closed {local: 0.0.0.0/0.0.0.0:3334, remote: null}
Hi Sergey,
Thank you for your reply.
I already noticed the mistake I had regarding the userSelectedID and fixed it, but it didn't change the behavior.
Now I ran the code suggested and got the same results.
I'm attaching 3 files:
1. Source code
2. The value of CmdRequest after first submit
3. The value of CmdResponse after first submit.
In addition, I noticed that
CmdRequest.Vehicles[0].Type is "VT_FIXED_WING" instead of "VT_MULTICOPTER".
To resolve this I tried the following:
int userSelectedIdx = 2;
Vehicle vehicle = task.Value.Objects[userSelectedIdx].Vehicle;
CmdRequest.Vehicles.Add(vehicle);
Now the value of CmdRequest.Vehicles[0].Type is "VT_MULTICOPTER", but the drone is still not armed.
Thank you for the help,
Nir.
Program.cs
CmdRequest.cs
CmdResponce.cs
Dear Nir,
Please use the following example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UGCS.Sdk.Protocol;
using UGCS.Sdk.Protocol.Encoding;
using UGCS.Sdk.Tasks;
using ProtoBuf;
namespace ArmTest
{
class Program
{
static void Main(string[] args)
{
/* Connects to UgCS server */
TcpClient tcpClient = new TcpClient("localhost", 3334);
MessageSender messageSender = new MessageSender(tcpClient.Session);
MessageReceiver messageReceiver = new MessageReceiver(tcpClient.Session);
MessageExecutor messageExecutor = new MessageExecutor(messageSender, messageReceiver, new InstantTaskScheduler());
messageExecutor.Configuration.DefaultTimeout = 10000;
var notificationListener = new NotificationListener();
messageReceiver.AddListener(-1, notificationListener);
/* Gets client ID */
AuthorizeHciRequest AuthRequest = new AuthorizeHciRequest();
AuthRequest.ClientId = -1;
AuthRequest.Locale = "en-US";
var future = messageExecutor.Submit<AuthorizeHciResponse>(AuthRequest);
future.Wait();
AuthorizeHciResponse AuthorizeHciResponse = future.Value;
int clientId = AuthorizeHciResponse.ClientId;
/* Logs into the server */
LoginRequest loginRequest = new LoginRequest();
loginRequest.UserLogin = "admin";
loginRequest.UserPassword = "admin";
loginRequest.ClientId = clientId;
var loginResponcetask = messageExecutor.Submit<LoginResponse>(loginRequest);
loginResponcetask.Wait();
/* Gets list of vehicles */
GetObjectListRequest getObjectListRequest = new GetObjectListRequest()
{
ClientId = clientId,
ObjectType = "Vehicle",
RefreshDependencies = true
};
getObjectListRequest.RefreshExcludes.Add("Avatar");
getObjectListRequest.RefreshExcludes.Add("PayloadProfile");
getObjectListRequest.RefreshExcludes.Add("Route");
var task = messageExecutor.Submit<GetObjectListResponse>(getObjectListRequest);
task.Wait();
/* Outputs found vehivles */
var list = task.Value;
foreach (var v in list.Objects)
{
System.Console.WriteLine(string.Format("Idx: {0}; name: {1}; id: {2}; type: {3}",
list.Objects.IndexOf(v), v.Vehicle.Name, v.Vehicle.Id, v.Vehicle.Type.ToString()));
}
System.Console.Write(string.Format("Select Vehicle Idx: "));
var userSelectedId = Convert.ToInt32(Console.ReadLine());
/* Sends ARM command */
SendCommandRequest CmdRequest = new SendCommandRequest
{
ClientId = clientId,
Command = new UGCS.Sdk.Protocol.Encoding.Command
{
Code = "arm",
Subsystem = Subsystem.S_FLIGHT_CONTROLLER,
}
};
CmdRequest.Vehicles.Add(new Vehicle() { Id = userSelectedId });
var CmdResponce = messageExecutor.Submit<SendCommandResponse>(CmdRequest);
CmdResponce.Wait();
System.Threading.Thread.Sleep(5000);
/* Sends DISARM command */
CmdRequest.Command = new UGCS.Sdk.Protocol.Encoding.Command
{
Code = "disarm",
Subsystem = Subsystem.S_FLIGHT_CONTROLLER,
};
CmdRequest.Vehicles.Add(new Vehicle() { Id = userSelectedId });
CmdResponce = messageExecutor.Submit<SendCommandResponse>(CmdRequest);
CmdResponce.Wait();
/* Clean ups */
tcpClient.Close();
messageSender.Cancel();
messageReceiver.Cancel();
messageExecutor.Close();
notificationListener.Dispose();
}
}
}
Best regards,
Sergey Zuev
www.ugcs.com/support