Can't arm DJI P3P using UgCS .NET sdk

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

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

You need to be a member of diydrones to add comments!

Join diydrones

Email me when people reply –

Replies

  • 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

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

  • 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?

  • Hi Nir,

    I checked your code and see that you use degrees in 

    new CommandArgument { Code = "latitude", Value = new Value { DoubleValue = 32.0698955 }},
    new CommandArgument { Code = "longitude", Value = new Value { DoubleValue = 34.7834508 }}

    They should be in radians.

    altitude_agl is a required parameter.

    heading is only optional

    Try:

    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 }}

  • Hi Nir, I am getting smiilar problem with EMU-COpter - see https://diydrones.com/group/ugcs/forum/topics/can-t-upload-route-to....

    I wonder if there is something generic about UGCS/SDK that we are missing?

    Stevod

    Can't upload route to EMU-COPTER using .Net SDK
    I am using the SDK to implement a full mission, including uploading a new route. The attached code Program.cs is heavily based on the Console example…
  • Hi Sergey,

    I decided to try and fly the Phantom 3 Pro using click&go. From the UgCS client it works well (on simulation)

    When I use the .NET UgCS console SDK exmaple (from here) I get the following error in the log file:

    2017-07-12 13:13:14,282 WARN [pool-9-thread-2] com.ugcs.ucs.service.command.CommandServiceImpl - Cannot send command
    com.ugcs.ucs.service.UcsException: Action requires exclusive vehicle control.

    I added AcquireLockRequest before the Click&Go example, and then I get:

    2017-07-12 13:17:17,798 DEBUG [pool-9-thread-1] com.ugcs.ucs.service.impl.LockServiceImpl - Vehicle:2 lock acquired by <User> admin
    2017-07-12 13:17:17,850 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 then modified the code to use vehicle 3 instead of vehicle 2 (which is my Phantom 3P) and I get:

    2017-07-12 13:20:15,478 DEBUG [pool-9-thread-1] com.ugcs.ucs.service.VehicleRadarService - Radar enabled for the vehicle [Phantom3-COPTER-70null].
    2017-07-12 13:20:15,478 DEBUG [pool-9-thread-1] com.ugcs.ucs.service.impl.LockServiceImpl - Vehicle:3 lock acquired by <User> admin
    2017-07-12 13:20:15,530 WARN [pool-9-thread-1] com.ugcs.ucs.vsm.proto.task.DeviceCommandTask - Argument not registered and will be omitted <arg> altitude_agl @ <cmd> waypoint @ FLIGHT_CONTROLLER#0
    2017-07-12 13:20:15,530 WARN [pool-9-thread-1] com.ugcs.ucs.vsm.proto.task.DeviceCommandTask - Value not specified for argument <arg> vertical_speed @ <cmd> waypoint @ FLIGHT_CONTROLLER#0, will send N/A

    2017-07-12 13:20:18,469 WARN [pool-9-thread-1] com.ugcs.ucs.service.command.CommandServiceImpl - Cannot read command result
    java.util.concurrent.ExecutionException: com.ugcs.ucs.service.VsmException: The distance between adjacent waypoints should be smaller than 2km. Note, that first and last waypoints are also considered as an adjacent.

    I did the following:

    1. Removed CommandArgument "altitude_agl"
    2. Added CommandArgument "verticle_speed" (=5)
    3. Modified altitude and longitude to fit my location

    I now get the following errors in the log:

    2017-07-12 13:28:59,252 DEBUG [pool-9-thread-1] com.ugcs.ucs.service.VehicleRadarService - Radar enabled for the vehicle [Phantom3-COPTER-70null].
    2017-07-12 13:28:59,252 DEBUG [pool-9-thread-1] com.ugcs.ucs.service.impl.LockServiceImpl - Vehicle:3 lock acquired by <User> admin
    2017-07-12 13:28:59,313 WARN [pool-9-thread-1] com.ugcs.ucs.service.command.CommandServiceImpl - Cannot send command
    com.ugcs.ucs.service.UcsException: Missing required argument value: location.

     

    I cannot find anything in the code or documentation about "location". What is the meaning of this argument? in what format should I specify it? an example will be great.

    Attached are code and logs of last run.

    Thank you for your help,
    Nir

    missing_argument_location_ucs.log

    Program.cs

    ugcs/ugcs-dotnet-sdk
    Contribute to ugcs/ugcs-dotnet-sdk development by creating an account on GitHub.
  • Hi Sergey,

    Looking at the Drone Specific Commands I see Phantom 3 only supports: Auto, Manual, Click&Go, Return Home, takeoff, land, Hold and Continue.

    Is there a place where of these command are explained?

    When using pixhawk I used the following commands: "mode guided" + "arm" + "takeoff" + "goto location" (several times).

    I'm looking to do the same with the Phantom 3 - is there a chance this can not be done and I have to plan a mission?

    Thank you

  • Hi Sergey,

    Again, thank you very much for help.

    I have tried the following sequences:

    1. AcquireLockRequest + SendCommandRequest(code = "takeoff_command") - no success*

    2. AcquireLockRequest + SendCommandRequest(code = "mnual") + SendCommandRequest(code = "takeoff_command") - still no success

    *I also tried "takeoff" instead of "takeoff_command", it didn't help.

    According to the Drone Specific commands these are supported by Phantom 3, but I'm still getting "Command not registered" exception (logs attached). What else might I be missing?

    ucs_lock_manual_takeoff_land.log

  • Dear Nir,

    Maybe you sending the command to the vehicle which does not support this command (2-th in your list).
    Please read supported commands of vehicles in "Drone specifics", p. 61 in "User manual":
    https://www.ugcs.com/files/manuals/v2.11/UgCS_User_manual_2.11_upda...

    Phantom 3 doesn't support "Arm" command.

    Best regards,
    Sergey Zuev
    www.ugcs.com/support

  • Hi Sergey,

    Attached are two file:

    1. The current source code

    2. The full log, from starting the UgCS server. My program starts at line 460.

    Program.cs

    ucs_full_log_using_device_with_lock.log

This reply was deleted.