Hello Tello Pilot!
Join our DJI Tello community & remove this banner.
Sign up

Has anyone decoded the log headers/messages from the Tello?

Excellent work guys. I'm going to try out adding a position feed from the Go package now...

Hello Stephen,
I logged (using your tello-term app, adding a file log function) the positions of an orbit flight around an object (camera was approximately pointing the center). I parsed the X,Y coordinates but I didn't find a circle fitting (while yaw axis was returning right values).
Moreover, I did a straight flight and measured the drawn distance. From the logged positions, I calculated the distance between initial and final position: comparing measurement with calculation, it seems that relative positions are expressed in meters.

Could you (or someone) please confirm those?

Changing topic: do you think will be possible to implement commands like move by certain distance or rotate by certain angle since it is feasible to close the feedback with position and orientation?
 
@Krag , @fcsorx
The DatCon quaternion code has been used now for a couple of years. Several of the platforms provide the OSD:pitch, OSD:roll, and OSD:Yaw signals which are then shown in the Go App. With the exception of the sampling rate the OSD values are identical to the values produced by the quaternion code. There are other rotation sequences, but at least this one matches what DJI is doing.

I suspect that sooner or later one of you guys are going to want the pitch and roll values for some computation. E.g., they are used in the InertialOnlyCalcs when computing velocity and position from just the accelerometers. The pitch and roll are needed to translate the body frame of reference accelerometer values to the gravitational field frame of reference.
 
Hello Stephen,
I logged (using your tello-term app, adding a file log function) the positions of an orbit flight around an object (camera was approximately pointing the center). I parsed the X,Y coordinates but I didn't find a circle fitting (while yaw axis was returning right values).
Moreover, I did a straight flight and measured the drawn distance. From the logged positions, I calculated the distance between initial and final position: comparing measurement with calculation, it seems that relative positions are expressed in meters.

Could you (or someone) please confirm those?

Changing topic: do you think will be possible to implement commands like move by certain distance or rotate by certain angle since it is feasible to close the feedback with position and orientation?

Hi - I'm slightly confused by the first part of your post; perhaps you could isolate individual issues and raise them on GitHub?

I'd really like to add 'move by' or 'move to' commands, but I'm not sure that is really possible/useful without a reliable North reference from the Tello? Or (hopefully) I'm wrong and it has some kind of magnetic compass...
 
Hi - I'm slightly confused by the first part of your post; perhaps you could isolate individual issues and raise them on GitHub?

I'd really like to add 'move by' or 'move to' commands, but I'm not sure that is really possible/useful without a reliable North reference from the Tello? Or (hopefully) I'm wrong and it has some kind of magnetic compass...

Sorry, I messed around the parsing of X,Y position of the flight of my tello. I attached the log of the orbital flight with an octave script to plot the path (X,Y,Rotation).Tello_Orbit.png
 

Attachments

  • logfile_circle.txt
    108.8 KB · Views: 18
  • Plot_XY_YAW.m.txt
    398 bytes · Views: 13
  • Like
Reactions: SMerrony
Actually I can't think of functional use for pitch and roll: except someone would like to monitor them during flips?
You could use the roll for leveling jpgs.

I was also thinking that the Tello might work for photogrammetry now that we have good position/orientation
@Krag , @fcsorx
The DatCon quaternion code has been used now for a couple of years. Several of the platforms provide the OSD:pitch, OSD:roll, and OSD:Yaw signals which are then shown in the Go App. With the exception of the sampling rate the OSD values are identical to the values produced by the quaternion code. There are other rotation sequences, but at least this one matches what DJI is doing.
Lets use that then. We want values that match DatCon and DJI instrumentation.

I'd really like to add 'move by' or 'move to' commands, but I'm not sure that is really possible/useful without a reliable North reference from the Tello? Or (hopefully) I'm wrong and it has some kind of magnetic compass...

The yaw is as reliable as the position its just not "north". Its whatever direction the Tello vision system picks up first (I think). You should still be able to use it for moveto.

If the user wants it to actually be north they could stick a little cracker jack compass on top and make sure it is always pointing North when they take off. :)
 
@Krag, @SMerrony

I attached a flow chart of simplest (maybe naive) implementation for a move command in XY plane (it's easily extendable to Up/Down or Rotate movements). Do you think is it feasible or am I wrong (or I simplified too much the problem)?Move_FlowChart.png
 
Last edited:
@Krag, @SMerrony

I attached a flow chart of simplest (maybe naive) implementation for a move command in XY plane (it's easily extendable to Up/Down or Rotate movements). Do you think is it feasible or am I wrong (or I simplified too much the problem)?

I don't follow it.

The whole problem is pretty complex. Why not start simple. Figure out how to turn (via fake stick input) until yaw is pointed at the target point. Once you have that done you can just move forward slowly (again via stick) until you reach the target.
 
The yaw is as reliable as the position its just not "north". Its whatever direction the Tello vision system picks up first (I think). You should still be able to use it for moveto.

If the user wants it to actually be north they could stick a little cracker jack compass on top and make sure it is always pointing North when they take off. :)

Hmm, I not convinced. Suppose I wanted to program the Tello to patrol a garden which was long and narrow, the smallest imprecision with the initial orientation would make 'moveto' commands useless and result in the drone crossing into a neighbour's property.

I suppose I am thinking that without GPS or a reliable compass, there are limits to what we can expect from our little 'toy' drone.
 
Here are my findings.

1. it regards yaw angle as 0 where the drone is powered on.
- can not find to reset yaw angle

2. roll, pitch and yaw angle are stable
- can use those information for OSD like the picture
- can use yaw for head tracking synchronized with phone orientation

3. MVO data is not stable enough..
- data are valid only when ambient light condition is good
: flags = _payload.getUnsignedByte(76); is always 8
: flags are valid, it was always 8 when it is not taken-off
- position is (0, 0) where the drone is powered on
: can not find to reset the position
- MVO_X and MVO_Y order seems reversed
: When the drone is moved straight forward, the MVO_X data are changed.
- the data unit is meter not centi meter(DataCon handles as Cm)

aTelloPilot.png
 
Last edited:
  • Like
Reactions: Krag and SMerrony
Here are my findings.

1. it regards yaw angle as 0 where the drone is powered on.
- can not find to reset yaw angle

2. roll, pitch and yaw angle are stable
- can use those information for OSD like the picture
- can use yaw for head tracking synchronized with phone orientation

3. MVO data is not stable enough..
- data are valid only when ambient light condition is good
: flags = _payload.getUnsignedByte(76); is always 8
: flags are valid, it was always 8 when it is not taken-off
- position is (0, 0) where the drone is powered on
: can not find to reset the position
- MVO_X and MVO_Y order seems reversed
: When the drone is moved straight forward, the MVO_X data are changed.
- the data unit is meter not centi meter(DataCon handles as Cm)

View attachment 643
In the tello .DATs that I've looked at the Yaw (computed from the quaternion) isn't initialized to 0.0

You're probably using the DatDefined MVO signals. And, yes those look to be expressed in centimeters. DatCon doesn't do any processing on DatDefined signals.

With version 3.6.0 DatCon has an Engineered version of the MVO signals where the units are meters and meters/sec. Also, the validity of the signals are incorporated meaning that values aren't reported if they are invalid.
1529589512830.png
 
  • Like
Reactions: Krag
Hmm, I not convinced. Suppose I wanted to program the Tello to patrol a garden which was long and narrow, the smallest imprecision with the initial orientation would make 'moveto' commands useless and result in the drone crossing into a neighbour's property.

I suppose I am thinking that without GPS or a reliable compass, there are limits to what we can expect from our little 'toy' drone.

Thats true. Its only as good as the vision/inertial system and setup will allow. But I am surprised looking back at my old ground tracks how accurate it is when flying around outdoors. Depending on what you want to do you could maybe fly the drone around the perimeter of the area to give it reference before executing whatever program.
 
To the end of putting together a glossary of the fields in the log I started work on building a spreadsheet with all of the fields and the ids, offsets, types etc defined in DatCon.

Once I had that it was only a quick change away from outputing the same data as json. I plan to use this to make a data driven parser for the Tello log stream. Here is how it works.

Code:
var records = TelloLib.TelloLog.Parse(byteData);//Parse any amount of log data.
foreach(var record in records)
{
    if(record.name== "new_mvo_feedback")//you could also use if (record.id == 0X1D)
    {
        foreach (var field in record.fields)
        {
            var str = string.Format("{0}.{1} = {2}", record.name, field.name, field.value);
            Console.WriteLine(str);
        }
    }
}
          
            Output is this:
new_mvo_feedback.visionObservationCount = 1282
new_mvo_feedback.Vel_X = 0
new_mvo_feedback.Vel_Y = 0
new_mvo_feedback.Vel_Z = 0
new_mvo_feedback.Pos_X = 0.01607675
new_mvo_feedback.Pos_Y = 0.01205779
new_mvo_feedback.Pos_Z = -0.004598673
new_mvo_feedback.hoverPointUncertainty1 = 1E-06
new_mvo_feedback.hoverPointUncertainty2 = 0
new_mvo_feedback.hoverPointUncertainty3 = 1
new_mvo_feedback.hoverPointUncertainty4 = 1E-06
new_mvo_feedback.hoverPointUncertainty5 = 0
new_mvo_feedback.hoverPointUncertainty6 = 1E-06
new_mvo_feedback.velocityUncertainty1 = 1E-06
new_mvo_feedback.velocityUncertainty2 = 0
new_mvo_feedback.velocityUncertainty3 = 0.007761657
new_mvo_feedback.velocityUncertainty4 = 1E-06
new_mvo_feedback.velocityUncertainty5 = 0.007282257
new_mvo_feedback.velocityUncertainty6 = 1E-06
new_mvo_feedback.height = -0.1
new_mvo_feedback.heightUncertainty = 0.02
new_mvo_feedback.reserved1 = 8
new_mvo_feedback.reserved2 = 0
new_mvo_feedback.reserved3 = 0
new_mvo_feedback.reserved4 = 10

Its not done yet but it handles all the record types and maybe 90% of the fields. Work in progress code is here:
Kragrathea/TelloLib

Spread sheet:
Kragrathea/TelloLib/parsedRecSpecs.csv

Json:
https://github.com/Kragrathea/TelloLib/blob/master/TelloLib/parsedRecSpecs.json

Attached is the output of a log I parsed to show all the fields.
 

Attachments

  • parsedLog.zip
    123.9 KB · Views: 10
  • Like
Reactions: Inakigarm
@SMerrony

Hi Stephen, as a "proof of concept", I implemented in your tello-term app ( adding an additonal case in mainloop: ) the possibility to rotate ccw the tello by a pre-defined angle (in degree) setting the variable TAngle. Sorry for the "quick and dirty" implementation (as I said befofere I'm a newbie in golang). I'd like to write an addictional flight command but I'm yet not experienced with channel, mutex, etc. I am sure you'll find a better implementation.

Code:
                    case 'm':
                    TAngle=45.0 //Set here Target Angle 0:180 [deg]
                    drone.Hover()
                    time.Sleep(1*time.Second)
                    QXi, _ = strconv.ParseFloat(fields[fQatX].value,64) // Initial Quaternion values
                    QYi, _ = strconv.ParseFloat(fields[fQatY].value,64)
                    QZi, _ = strconv.ParseFloat(fields[fQatZ].value,64)
                    QWi, _ = strconv.ParseFloat(fields[fQatW].value,64)
                    _, _, ITheta = toEuler (float32(QXi), float32(QYi), float32(QZi), float32(QWi))
                    ITheta = ITheta*180/math.Pi // Initial Angle value [deg]
                    drone.CounterClockwise(int(TAngle/180*100)) //Set Speed proportional to Target Angle
                    DeltaAngle=0.0
                    for DeltaAngle <= TAngle {  //Rotate until Target Angle
                        QX, _ = strconv.ParseFloat(fields[fQatX].value,64)
                        QY, _ = strconv.ParseFloat(fields[fQatY].value,64)
                        QZ, _ = strconv.ParseFloat(fields[fQatZ].value,64)
                        QW, _ = strconv.ParseFloat(fields[fQatW].value,64)
                        _, _, Theta = toEuler (float32(QX), float32(QY), float32(QZ), float32(QW))
                        Theta = Theta*180/math.Pi
                        DeltaAngle=math.Abs(Theta-ITheta)
                        time.Sleep(updatePeriodMs * time.Millisecond)
                    }
                    drone.Hover()
 
  • Like
Reactions: SMerrony
@fcsorx

:) I will look at doing something similar inside the package over this weekend.

Perhaps I'll just start with a TurnByDeg(d) func where -360<d<360.
 
I don't think you are on the right track. If you do a TurnBy function then all you can only do one thing at a time. Ie you would need a TurnByAndClimb function.

What you want is a function that is called every heartbeat that calculates what the stick input should be based on targets.
Code:
var targetX, targetY;
var action = none;

                    case 'm':
                        targetX=0;targetY=0;
                        action= flyTo;


OnTick()//Called every heartbeat or as frequently as possible
{
    if(action==flyTo)
        //calc turn part.
        desiredYaw = calcYawToTarget(myX,myY,targetX,targetY)
        deltaYaw = desiredYaw-myYaw
        if(abs(deltaYaw)>minYawAmount)
        {
            if(deltaYaw>0)
                joyLx=0.10;//10% right joystick
            else
                joyLx=-0.10;//10% left joystick
        }
        //calc Up/Down input.
        //etc...

       if(joyLx==0 && joyLy==0 && ... )//Check for no input.
            action=none;//Done turning back to hover.
 
}
 
I don't think you are on the right track. If you do a TurnBy function then all you can only do one thing at a time. Ie you would need a TurnByAndClimb function.

That's not the "Go Way"!;)

I've started on some auto-flight functions: FlyToHeight() and FlyToYaw(). They seem to be working OK, and of course, being Go, you can call both at the same time and the Tello will twist and rise together saving time and battery.
 
  • Like
Reactions: messenio and fcsorx
That might work ok for height and yaw but what about flying to a target point. What if the target is moving? Or if you are flying to a fixed point and need to refine yaw as you get closer.
 
@SMerrony
Hi Stephen, just a little contribution: I implemented a function to move right by a distance d (in cm). It seemed to work. It's easy extendable to other directions in XY plane.

Code:
func (tello *Tello) MoveRight(d int) { //Target distance d [cm]
    tello.Hover()
    Xi := float64(tello.GetFlightData().MVO.PositionX) //Initial X,Y position
    Yi := float64(tello.GetFlightData().MVO.PositionY)
    tello.Right(20) //TODO: Set speed proportional to distance
    IDist := 0.0
    for IDist <= float64(d) {  //Move until Distance = Target Distance
                                     X := float64(tello.GetFlightData().MVO.PositionX)
                                     Y := float64(tello.GetFlightData().MVO.PositionY)
                                     IDist = 100*math.Sqrt((X-Xi)*(X-Xi)+(Y-Yi)*(Y-Yi)) // Distance from initial position [cm]
                                     time.Sleep(50 * time.Millisecond) // Sample distance every 50m
    }
    tello.Hover()
    }
 
  • Like
Reactions: SMerrony and Cyke
That might work ok for height and yaw but what about flying to a target point. What if the target is moving? Or if you are flying to a fixed point and need to refine yaw as you get closer.
I may change my mind, but at the moment I think most of that is out of scope for my Tello control/telemetry package. I could envisage a higher-level package or application which uses mine to achieve target tracking etc.

Still, I am going to try out some horizontal movement and see how it goes...
 

New Posts

Members online

No members online now.

Forum statistics

Threads
5,690
Messages
39,934
Members
17,023
Latest member
Repiv

New Posts