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: 358

Replies to This Discussion

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/span>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/span>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/span>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.Namev.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/span>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/span>SendCommandResponse>(CmdRequest);

            CmdResponce.Wait();



            /* Clean ups */

            tcpClient.Close();

            messageSender.Cancel();

            messageReceiver.Cancel();

            messageExecutor.Close();

            notificationListener.Dispose();

        }

    }

}

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

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.

Attachments:

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}

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?

Dear Nir,

Could you send me the full log and new your programme?

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.

Attachments:

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,

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?

Attachments:

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,

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

Attachments:

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

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

RSS

© 2017   Created by Chris Anderson.   Powered by

Badges  |  Report an Issue  |  Terms of Service