3

What is my issue?

When I say "Blink green" the drone will do exactly what I want. That works great.

When I say "Blink green" again, it will execute the code, but the drone doesn't give a response. The drone gives only a response in the first time. So every time I have to restart the program to make it work. Annoying...

What happens the second time?

It will do exactly the same, it's executing the code as well, but the drone doesn't give a response.

Here's the code:

private static void _speechRecognitionEngine_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    switch (e.Result.Text)
    {
        case "Blink green":
            Task.Run((Action)blinkGreen);
            break;
    }
}

// ONLY WORKS THE FIRST TIME
// WHEN I SAY "BLINK GREEN" AGAIN, IT'S WILL EXECUTE THE 
// CODE BUT THE DRONE DOESN'T GIVE A RESPONSE. ONLY THE 
// FIRST TIME (SO I HAVE TO RESTART THE PROGRAM)
public static async void blinkGreen()
{
    var func = Edge.Func(@"
        var arDrone = require('ar-drone');
        var client = arDrone.createClient(); 

        return function(data, callback){
            client.animateLeds('blinkGreen',5,2);
            callback(null, data);
        }
    ");
    Console.WriteLine(await func("BLINK EXECUTED!"));
}

I think something is going on with:

var arDrone = require('ar-drone');
var client = arDrone.createClient(); 

I am allowed to create one client I guess. I have to create and reuse the client instance, so I can use the same client which would solve the problem. But I have no idea how to do that with the Edge.js module...

I hope someone could help me out with this problem.

Thanks,

Jamie

6
  • I'm not familiar with the ar-drone library but maybe only one client can be connected at a time? If you can create and reuse the client instance that may work. Commented Feb 12, 2016 at 22:32
  • @Cyral, I think the problem is that I am allowed to create one client what you said already. Do you have an idea how I can use one client? Commented Feb 13, 2016 at 17:31
  • I just saw this question in my feed but I don't know much about running NodeJS in C#. You would need to somehow create the client once as a global variable but still have access to it later on. Commented Feb 13, 2016 at 17:32
  • @Cyral, that would fix the problem to create and reuse the client instance, but I have no idea how... Commented Feb 13, 2016 at 17:35
  • Yeah sorry that's about all I can offer, not familiar with this. Commented Feb 13, 2016 at 17:35

3 Answers 3

1

@Jay >

I am a little bit further, let's see what I did.

  1. I have created one boolean to check if there's already one client and one variable to save the client.

    static bool clientCreated = false;
    static object currentClient;
    
  2. In the beginning of the program I've created a check to get an existing or new client

        // First check to get an existing or new client
        currentClient = GetOrCreateClient();
    
  3. I've created a method to return an existing or new client

    public static object GetOrCreateClient()
    {
        // If there is already a client
        if (clientCreated)
        {
            Console.WriteLine("There's already a client!");
        }
        // If there is no client
        else
        {
            // Set boolean
            clientCreated = true;
    
            // Create a client
            var newClient = Edge.Func(@"
                var arDrone = require('ar-drone');
                var client = arDrone.createClient();
    
                return function(data, callback){
                    callback(null, data);
                }
            ");
    
            Console.WriteLine("Client created!");
    
            // Return new client
            return newClient;
        }
        // Return current client
        return currentClient;
    }
    
  4. And the functionality method to do an action (animation of the drone) which should use the same client

    public static async void blinkGreen()
    {
        // Get an existing or new client
        var client = GetOrCreateClient();
    
        // Execute the functionality
        var func = Edge.Func(@"             
            var arDrone = require('ar-drone'); // ACTUALLY THIS ONE IS ALREADY DEFINED IN THE METHOD GetOrCreateClient()
            var client = I WANT HERE THE CLIENT, BUT HOW?
    
            return function(data, callback){
                client.animateLeds('blinkGreen',5,2);
                callback(null, data);
            }
        ");
        Console.WriteLine(await func("BLINK EXECUTED!"));
    }
    

Now I am stuck on a few things, because is that the right way to save the client globally in an object? Because the method GetOrCreateClient() returns the following object:

`System.Func`2[System.Object,System.Threading.Tasks.Task`1[System.Object]]`

So my next question would be, how can I use the client object into the functionality?

The var client = GetOrCreateClient();

variable should placed into:

        var func = Edge.Func(@"             
            var arDrone = require('ar-drone'); // ACTUALLY THIS ONE IS ALREADY DEFINED IN THE METHOD GetOrCreateClient()
            var client = I WANT HERE THE CLIENT, BUT HOW?

The other way to disconnect the client would be solve the problem as well, but cost more overhead and latency indeed.

Sign up to request clarification or add additional context in comments.

Comments

1

I honestly haven't used Edge.js but I can see your issue from the example your posting.

Why don't you break apart the Edge functionality into separate functions on the class.

E.g. define the edge functionality for creating the client and returning it, if the client is already created then return the existing client. Call this function GetOrCreateClient.

Then define the calls which need the client to take a client object so if you have multiple clients for multiple drones you can make each blink separately.

Finally interpret the voice commands and dispatch as necessary to the appropriate client for the drone using the GetOrCreateClient function to get the client for the correct drone.

I can write some code to help you with this but I would like to see how you get there from what I explained first rather than just writing it for you.

The other way would be to disconnect the client after receiving the response but this will cost more overhead and latency when issuing commands.

UPDATE

To share data between function calls I think you need to export the variable or function you want to be shared.

There may be an export function or a window or GLOBAL object which can be augmented with the variable you need to export.

As far as your current approach, you seen to want to define the logic in C#, since the logic is occurring in Javascript you can actually define GetOrCreateClient in edge.js function, pretty much like you have in C# but in Javascript.

'function GetOrCreateClient(){ return !this.client ? this.client=require ('ardone') : this.client; }'

This can be defined right before you handle the call to blinkGreen.

Then make client = GetOrCreateClient in the javascript, The first time it will create the client and the second time it will return the existing client.

Then make the call to blinkGreen as you need to do.

Finally, C# already has an Ardone library, unless you need Node it would make sense to me to keep Node out of the equation and just use c# alone for this.

1 Comment

Hello @Jay, thank you for your explanation. I will try this tomorrow and let you know about the results.
0

I am not familiar with this library, but most NodeJS requires are cached, so only the portion inside the function will be run more than once. Try moving your animateLeds call inside the returned function, like so:

public static void blinkGreen()
{
    var func = Edge.Func(@"
        var arDrone = require('ar-drone');
        var client = arDrone.createClient();

        return function(data, callback){
            client.animateLeds('blinkGreen',5,2);
            callback(null, data);
        }
    ");
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.