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();
}
}
}

------------------------------------

Views: 364

Replies to This Discussion

Hi Igor,

Thank you for your help. I tried using the CommandArgument you specified and now I'm getting the following error:

2017-07-13 17:11:38,676 WARN [pool-9-thread-1] com.ugcs.ucs.service.command.CommandServiceImpl - Cannot send command
com.ugcs.ucs.service.UcsException: Command can't be send: please specify take-off point altitude for the drone.

I tried to use the following, but it didn't help:

new CommandArgument { Code = "takeoff_altitude", Value = new Value { DoubleValue = 5.0 }},
new CommandArgument { Code = "latitude", Value = new Value { DoubleValue = 0.5597252672441 }},
new CommandArgument { Code = "longitude", Value = new Value { DoubleValue = 0.6070857416639 }},
new CommandArgument { Code = "altitude_agl", Value = new Value { DoubleValue = 5.0 }},
new CommandArgument { Code = "ground_speed", Value = new Value { DoubleValue = 5.0 }},

How do I specify take-off point altitude?

To set takeoff point you need to do the following steps: 

1) Get vehicle object from UCS server: 

GetObjectRequest requestVehicle = new GetObjectRequest()
{
  ClientId = clientId,
  ObjectType = "Vehicle",
  ObjectId = 3, 
  RefreshDependencies = true
};
var responseVehicle = messageExecutor.Submit<GetObjectResponse>(requestVehicle);
responseVehicle.Wait();

2) set attitude origin property of the vehicle

var vehicle = responseVehicle.Value.Object.Vehicle;
vehicle.AltitudeOrigin = 0.1;

This is very important to know your vehicle position ground elevation. You can get it from telemetry (Telemetry.Elevation) or use GetRasterValuesRequest

For test purposes, you can get it from takeoff point window in UgCS

3) update vehicle

UpdateObjectFieldsRequest fieldUpdateRequest = new UpdateObjectFieldsRequest
{
ClientId = clientId,
ObjectType = "Vehicle",
Object = new DomainObjectWrapper().Put(vehicle, "Vehicle"),
};
fieldUpdateRequest.FieldNames.AddRange(new string[] { "altitudeOrigin" });

var task = messageExecutor.Submit<UpdateObjectFieldsResponse>(fieldUpdateRequest);
task.Wait();

Please remove takeoff_altitude from click-to-go command arguments.

it has only 5 parameters:

latitude, longitude, altitude_agl, ground_speed - are required

heading - optional

RSS

© 2017   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service