How to implement rc command on virtual joystick? - dji-sdk

I need to implement a Tello command, which is rc a b c d on a virtual joystick. From different forums, I came to know that for virtual joystick, we need to use rc commands to move the Tello drone. But I don't know how to implement it. In their SDK documentation, they have mentioned it as
a:left/right (-100~100) b: forward/backward (-100~100) c: up/down (-100~100) d: yaw (-100~100)
What do these negative values mean? How can I use the rc command to move the drone?
This is the virtual joystick code which I am using:
JoystickView joystick = (JoystickView) findViewById(R.id.joystickView);
joystick.setOnMoveListener(new JoystickView.OnMoveListener() {
#Override
public void onMove(int angle, int strength) {
// code goes here
}
});

The values -100~100 normally are the velocity for their respective axis. Depending on the coordinate system set and the control modes for the axes, the aircraft move along the axis corresponding to the value. Based on the code you provided I assume the strength value represents the percentage how much the stick is pushed/shifted and the angle value shows the direction into which the stick is pushed.
For the virtual Sticks you need to set the Control modes and coordinate system by accessing the flight Controller:
setRollPitchControlMode(RollPitchControlMode.VELOCITY);
setYawControlMode(YawControlMode.ANGULAR_VELOCITY);
setVerticalControlMode(VerticalControlMode.VELOCITY);
setRollPitchCoordinateSystem(FlightCoordinateSystem.BODY);
The modes chosen above ensure that the virtual controller behaves the same as the default physical remote controller.
Additionally you need to activate the virtual Sticks with the setVirtualStickModeEnabled method before you can use them.
Now for the continuous control over the aircraft you need to send the virtualStickData with at least 5 Hz:
SendVirtualStickDataTask task = new SendVirtualStickDataTask();
this.timer = new Timer();
this.timer.schedule(task, 0, 200);
In this example SendVirtualStickDataTask extends TimerTask and only sends the current pitch, roll, yaw, and vertical throttle values to the drone via the sendVirtualStickFlightControlData method from DJI SDK inside the run() method of TimerTask.
Finally the current pitch, roll, yaw, and vertical throttle values are set inside your onMove() method you posted in your question. E.g. you can use the trigonometric functions sin and cos to determine the x- and y- parts of the strength value, something like this:
pitch = Math.cos(angle)*strength;
roll = Math.sin(angle)*strength;
Please note that the angle needs to be radian and you probably need to cast the angle/strength to float. Furthermore depending on how the angle value is determined you need to adjust the value accordingly.
The second joystick can be used to control the vertical throttle and the yaw. you will need a bit of fine-tuning and testing.
For the control modes/coordinate system, the following DJI SDK Documentation is helpful (scroll down to "Virtual Sticks"):
https://developer.dji.com/mobile-sdk/documentation/introduction/component-guide-flightController.html
DJI also has a basic code example for the virtual Sticks usage:
https://developer.dji.com/mobile-sdk/documentation/android-tutorials/SimulatorDemo.html
I highly recommend using the DJI Flight Assistant 2 Software to test your code before you attempt to fly in the real world.

Related

How to set a Sprite to a specific Frame in Godot

I have the Player move around and when he enters a new Room (via Instancing) his Sprite shows him facing in the Default direction (in my Case down). So If you enter a Room from any other direction then it looks weird, cause for a short Moment you can see the Player facing down even if you came from the right. How can I tell Godot to set the Player Sprite to a specific Frame in Code, so I can set it to the proper Frame for each Direction. I'm new to Godot and I used HeartBeast Action RPG Tutorial for my Movement. So it's using an AnimationTree and AnimationPlayer. I tried "set_frame" but Godot just says it doesn't know the Method.
If you are following the tutorial series I think you are following (Godot Action RPG)… You are using an AnimationTree with AnimationNodeBlendSpace2D (BlendSpace2D).
The BlendSpace2D picks an animation based on an input vector "blend_position". This way you can use BlendSpace2D to pick an animation based on the direction of motion or the direction the player character is looking at. For example, you can "idle_up", "idle_down", "idle_left", and "idle_right" animations, and use BlendSpace2D to pick one in runtime based on a direction vector.
Thus, you need to set the "blend_position" of the BlendSpace2D like this:
animationTree.set("parameters/NameOfTheBlendSpàce2D/blend_position", vector)
Where:
animationTree is a variable set to the AnimationTree.
"NameOfTheBlendSpàce2D" is the name of the BlendSpace2D you want to set (e.g. "Idle").
vector is a Vector2D with the direction you want (e.g. Vector2.UP).
This is shown in the episode 6 of the tutorial series (Animation in all directions with an AnimationTree).
You can find a reference project by HeartBeast at arpg-reference, where you can find a function update_animation_blend_positions that looks like this:
func update_animation_blend_positions():
animationTree.set("parameters/Idle/blend_position", input_vector)
animationTree.set("parameters/Run/blend_position", input_vector)
animationTree.set("parameters/Attack/blend_position", input_vector)
animationTree.set("parameters/Roll/blend_position", input_vector)
Here "Idle", "Run", "Attack", and "Roll" are BlendSpace2D, each configured with animations for the corresponding actions, and this function updates them in sync so that they are picking the correct animation.
As far as I can tell the code from the repository is further refactored from what is show in the tutorial series. This code from the repository is under MIT licence.

Projecting negative coordinates inside display area

I am testing the RandomWaypointMobility with a constrained area minX=-3000m, maxX=3000m, minY=-3000m and maxY=3000m. The #displaystrings sets bgp=6000,6000. The result is that nodes in the negative part of the coordinate system are rendered outside the display/canvas area.
Are there some parameters I can use to tell OMNeT++/INET that origo for the coordinate system is at the center of the display/canvas? I have tried
*.visualizer.sceneVisualizer.sceneMaxX = 3000m
*.visualizer.sceneVisualizer.sceneMinX = -3000m
*.visualizer.sceneVisualizer.sceneMaxY = 3000m
*.visualizer.sceneVisualizer.sceneMinY = -3000m
*.visualizer.sceneVisualizer.sceneMaxZ = 3000m
*.visualizer.sceneVisualizer.sceneMinZ = -3000m
but it doesn't work as I hoped for.
I realize that for RandomWaypointMobility I can just use a constrained area with positive coordinates only, which would keep objects within the canvas. However, my next task is to pull in mobility traces that include negative coordinates. Do I need to manually shift all coordinates so they become positive and stay within the canvas/display, or is there a smarter way of doing things?
Any hints appreciated!
Thanks,
Dragos
What you set is in fact bgb=6000,6000 which sets the size of the module. There were indeed plans to add a tag called bgp directly into OMNeT++ which would introduce an offset, but at the end it was not implemented. The reason is that once you go down into that rabbit hole, you want to implement also scaling and then rotation etc. So the default display string based visualization left as simple as possible and all these transformation stuff was left for the model code.
So indeed, SceneCanvasVisualizer in INET has a viewScale and viewTranslation parameter that can be used for these purposes.

Vertical takeoff for a DJI Matrice 100

DJI Android SDK version: 4.11
Matrice 100 / Matrice 600
I am trying to take off the drone vertically.
I tried with GoToAction in a timeline, but that failed due to some bug in the SDK, (confirmed by your support team dev#dji.com #29496) I get STARTED for the GoToAction, but no PROGRESSED or FINISHED, and no errors logged at all.
Since I need to continue working, I tried a workaround by sending FlightControlData to the VirtualStick by calling the following function with the requested height 20 times a second:
VerticalControlMode.POSITION
FlightOrientationMode.AIRCRAFT_HEADING
VirtualStickModeEnabled = true
VirtualStickAdvancedModeEnabled = true
void sendHeightCommand(Float requestedAltitude) {
FlightControlData data = new FlightControlData(0f, 0f, 0f, requestedAltitude);
flightController.sendVirtualStickFlightControlData(data, djiError -> {
log.v(djiError.getDescription);
});
}
And it works (with the right amount of timeouts) but if there is wind, the drone drifts away, which is very dangerous for me as there is more than one drone in the field, and I don't want them to collide.
Is there another way to change the altitude of the drone, while maintaining its position?
Or is there a way to measure the wind, and push back against it?
[*] Take off drone vertically:
I always use the TakeOffAction in the timelineMission before the GoToAction to ascend to the desired height. However I'm using a Mavic Pro and the SDK may behave different with a matrice drone.
When using the FlightControlData with the VirtualSticks, I use the startPrecisionTakeoff() method in the FlightController class; after the takeoff, the drone ascends to the desired position when the flight control data is sent continuously.
[*] stable hovering:
For the hovering the only low cost solution I see is to enable the VisionAssistedPositioning in the FlightAssistant class, I don't know if the Matrice supports this feature as the documentation doesn't say anything on the supported aircrafts.
Ok so the solution was to use the function: setVirtualStickAdvancedModeEnabled(true)
The reason I didn't see any results was because in the simulator I was playing with 20.0 North Wind, which apparently is too much.
When I lowered it to 5.0 it works perfectly.

DJI SDK Android - unwanted yaw motion on GoToAction in time line mission

I am trying to develop a mobile application using DJI Mobile Android SDK. The goal of the application is navigate a Mavic 2 Pro to a target GPS coordinates and automatically center a camera on a vehicle and take a snapshot. After taking off and flying to target altitude a new tracking mission in spotlight mode is called to find an object and center a camera on it.
The first process goes normally after an aircraft is turned on and the mobile application runs the missions. The aircraft is landed manually.
The second trial with the mobile application goes wrong. There is an additional yaw motion that is not in time line mission. I have missed some cleaning method that reset the aircraft to an initial clean state probably.
How to setup the aircraft to a clean state before the application starts the missions please?
I don't understand why there is a yaw 45° motion in a simple
time line mission:
missionControl.scheduleElement(new TakeOffAction());
missionControl.scheduleElement(new GoToAction(2.0f));
missionControl.startTimeline();
Why the aircraft yaw 45° after the takeoff while it is lifting to target
altitude? It's to see https://youtu.be/-gCWFXou-WI
You never share any other code. so below is my list of guess/checklist for a possible solution.
First, clear all other code, e.g disable drone yaw following or any other possible routing with the keyword of tracking/following etc from both code and remote controller screen
The easiest way to check if it caused by this is to call
elements.add(new GoToAction(new LocationCoordinate2D(homeLatitude+0.00001, homeLongitude+0.00001), 5));
elements.add(new GoToAction(new LocationCoordinate2D(homeLatitude-0.00001, homeLongitude-0.00001), 5));
if the camera still follows you while at a multiple location. Then sth at tracking is bothering you. If follow it could be caused by home lock also
Secondly, GoToAction never mentions about the orientation but only 3D position. Theoretically, they can do anything they want. so check API for all orientation method/setting e.g
Use setFlightOrientationMode to set course lock or home lock to get your desired behavior.
method setFlightOrientationMode
void setFlightOrientationMode(#NonNull FlightOrientationMode type,
#Nullable CompletionCallback callback)
Package: dji.sdk.flightcontroller
SDK Key: FlightControllerKey.ORIENTATION_MODE
Description:
Sets the aircraft flight orientation relative to the Aircraft Heading, Course Lock, or Home Lock. See the Flight Controller User Guide for more information about flight orientation.
Last I assume you removed all other possible following modes and it is still not behave according to your wish.
The api given is
GoToAction(LocationCoordinate2D coordinate)
GoToAction(float altitude)
float altitude Target altitude in meters.
GoToAction(LocationCoordinate2D coordinate, float altitude)
If the direct setting altitude has an issue. Can you try the full command to determine it is a bug in the source code or it is sth else
double homeLatitude = get your start gps lat;
double homeLongitude = get your start gps long;
elements.add(new GoToAction(new LocationCoordinate2D(homeLatitude, homeLongitude), 2));
If you are sure that you have no other routing that bothers the drone, and both GoToAction(float altitude) and GoToAction(LocationCoordinate2D coordinate, float altitude) has the same yaw problem. open a ticket in dev#dji.com.
Personally, I don't think it is DJI`s issue. Because you never post the full code so I have no idea what you have done or you haven't have done but should have done. So good luck in finding the solution to your unwanted behavior.

How to find device position change using accelerometer?

I am designing a Windows Phone 7 project where I need to determine position changes of the device. I tried to use accelerometer, but it gives info on current orientation of my phone and I don't know how to convert this data to position delta. Here is some example code:
void acc_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
{
AccelerometerReading newdata = e.SensorReading;
Vector3 vect = newdata.Acceleration - data.Acceleration;
//what comes here???
}
The method above is called when accelerometer data is changed. But I don't know how to convert this data to position change of a device (i.e. I move my phone in X direction)
You can't do it.
You get position by integrating the linear acceleration twice but the error is horrible. It is useless in practice.
See the above linked answer to get some ideas what you actually can do.

Resources