Code Monkey home page Code Monkey logo

gomavlib's People

Contributors

aler9 avatar ddries avatar dependabot[bot] avatar justinclift avatar menzels avatar sirno-baka avatar twpayne avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

gomavlib's Issues

undefined: CELLULAR_NETWORK_FAILED_REASON

Hello Everyone,

I am using "gomavlib" in my project. But, I've met an issue recently.
Does anyone know how to solve the problem described below?

PS agent\cmd> go run .\main.go
# github.com/aler9/gomavlib/pkg/dialects/common
..\..\..\..\..\..\go\pkg\mod\github.com\aler9\[email protected]\pkg\dialects\common\dialect.go:17730:16: undefined: CELLULAR_NETWORK_FAILED_REASON
..\..\..\..\..\..\go\pkg\mod\github.com\aler9\[email protected]\pkg\dialects\common\dialect.go:17732:7: undefined: CELLULAR_NETWORK_RADIO_TYPE

Enums are incorrectly treated as bit masks when converted to strings

Enumerated types like MAV_STATE are incorrectly treated as bitmasks when converted to strings.

Example:

package main

import (
	"os"

	"github.com/bluenviron/gomavlib/v2/pkg/dialects/minimal"
)

func main() {
	state := minimal.MAV_STATE_STANDBY
	data, _ := state.MarshalText()
	os.Stdout.Write(data)
}

This should print

MAV_STATE_STANDBY

but actually prints

MAV_STATE_UNINIT | MAV_STATE_CALIBRATING | MAV_STATE_BOOT | MAV_STATE_STANDBY

The problem is that the generated MAV_STATE.MarshalText function treats MAV_STATE as a bitmask, whereas it is actually an enum.

This same bug likely affects all other enums.

Decoder panics

I get a panic here https://github.com/aler9/gomavlib/blob/master/pkg/msg/decencoder.go#L397 when a plane goes into landing procedure. As it happens only when airborne (couldn't reproduce it on a simulator) it's hard to tell which message it was. Maybe someone will have an idea? I'm fine to write a test for it and send a PR. A quick workaround was changing that line to:

for end < len(buf) && buf[end] != 0 && end < int(f.arrayLength) {

The stack trace:

panic: runtime error: index out of range [50] with length 50

goroutine 60 [running]:
github.com/aler9/gomavlib.decodeValue(0x2f69c8, 0x200f374, 0x198, 0x2100281, 0x32, 0x32, 0x217cf20, 0x1)
	/home/user/go/pkg/mod/github.com/aler9/[email protected]/dialect.go:415 +0x74c
github.com/aler9/gomavlib.(*dialectMessage).decode(0x217cda0, 0x2100281, 0x32, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0)
	/home/user/go/pkg/mod/github.com/aler9/[email protected]/dialect.go:325 +0x258
github.com/aler9/gomavlib.(*Parser).Read(0x24ce1e0, 0x203efc4, 0x211d2a0, 0x0, 0x0)
	/home/user/go/pkg/mod/github.com/aler9/[email protected]/parser.go:305 +0x5d4
github.com/aler9/gomavlib.(*Channel).run.func1(0x20121c0, 0x20278c0)
	/home/user/go/pkg/mod/github.com/aler9/[email protected]/channel.go:73 +0xc4
created by github.com/aler9/gomavlib.(*Channel).run
	/home/user/go/pkg/mod/github.com/aler9/[email protected]/channel.go:65 +0x48

Help on getting a minimal local example

Hello, I wanted to set up a minimal working example of message interchange between two processes on my machine using UDP broadcast. So far I have this:

Broadcaster

package main

import (
	"fmt"
	"mavtest"

	"github.com/aler9/gomavlib"
	"github.com/aler9/gomavlib/pkg/dialects/ardupilotmega"
)

func main() {
	// create a node which
	// - communicates with a serial port
	// - understands ardupilotmega dialect
	// - writes messages with given system id
	node, err := gomavlib.NewNode(gomavlib.NodeConf{
		Endpoints: []gomavlib.EndpointConf{
			gomavlib.EndpointUDPBroadcast{BroadcastAddress: "192.168.1.255:5660"},
		},
		Dialect:     ardupilotmega.Dialect,
		OutVersion:  gomavlib.V2, // change to V1 if you're unable to communicate with the target
		OutSystemID: 1,
	})
	if err != nil {
		panic(err)
	}
	defer node.Close()
	msg := &ardupilotmega.MessageParamValue{
		ParamId:    "test_parameter",
		ParamValue: 123456,
		ParamType:  ardupilotmega.MAV_PARAM_TYPE_UINT32,
	}
	node.WriteMessageAll(msg)
	for evt := range node.Events() {

		if frm, ok := evt.(*gomavlib.EventFrame); ok {
			fmt.Printf("received: id=%d, %+v\n", frm.Message().GetID(), frm.Message())

			// if message is a parameter read request addressed to this node
			if msg, ok := frm.Message().(*ardupilotmega.MessageParamRequestRead); ok &&
				msg.TargetSystem == 10 &&
				msg.TargetComponent == 1 &&
				msg.ParamId == "test_parameter" {

				// reply to sender (and no one else) and provide the requested parameter
				node.WriteMessageTo(frm.Channel, &ardupilotmega.MessageParamValue{
					ParamId:    "test_parameter",
					ParamValue: 123456,
					ParamType:  ardupilotmega.MAV_PARAM_TYPE_UINT32,
				})
			}
		}
	}
}

Client

package main

import (
	"fmt"
	"mavtest"

	"github.com/aler9/gomavlib"
	"github.com/aler9/gomavlib/pkg/dialects/ardupilotmega"
)

func main() {
	// create a node which
	// - communicates with an UDP endpoint in client mode
	// - understands ardupilotmega dialect
	// - writes messages with given system id
	node, err := gomavlib.NewNode(gomavlib.NodeConf{
		Endpoints: []gomavlib.EndpointConf{
			gomavlib.EndpointUDPClient{"0.0.0.0:5660"},
		},
		Dialect:     ardupilotmega.Dialect,
		OutVersion:  gomavlib.V2, // change to V1 if you're unable to communicate with the target
		OutSystemID: 10,
	})
	if err != nil {
		panic(err)
	}
	defer node.Close()

	// print every message we receive
	for evt := range node.Events() {
		if frm, ok := evt.(*gomavlib.EventFrame); ok {
			fmt.Printf("received: id=%d, %+v\n", frm.Message().GetID(), frm.Message())
		}
	}
}

But no messages are coming through on either of them.

UDP Broadcast example panics

Running the example on my linux machine yields the following on NewNode:

panic: cannot find local address associated with given broadcast address
$ go version
go version go1.16.3 linux/amd64

Relaying a message with a different sourceSystemID

I am trying to change the contents of a message before relaying it, however, i need to also change the sourceSystemId and sourceComponentID.

I need to set it to the original values from the frame.
Any help is highly appreciated.

` for evt := range node.Events() {
if frm, ok := evt.(*gomavlib.EventFrame); ok {

		if frm.Message().GetID() == 269 {
			msg := frm.Message().(*common.MessageVideoStreamInformation)

			msg.Uri = strings.Replace(msg.Uri, "127.0.0.1", "10.2.2.112", 1)
			fmt.Printf("received: id=%d, %+v\n", frm.Message().GetID(), msg)
			node.WriteMessageExcept(frm.Channel, msg)`

about gomavlib and mavsdk-go

May I ask a stupid question ?

What's the difference between gomavlib and mavsdk-go( github.com/mavlink/MAVSDK-Go ) ?

I am learning something on PX4( flight control software) and don't know which one should I choose .
Thanks for any information .

bug in enum MarshalText() methods

I found a bug in MarshalText() methods for enum

For example, in the common.MAV_SYS_STATUS_SENSOR type when executing MarshalText()

Example:
text, err := (common.MAV_SYS_STATUS_SENSOR_3D_GYRO | common.MAV_SYS_STATUS_SENSOR_3D_ACCEL).MarshalText()

There will be an "invalid value" error, since the method looks at labels_MAV_SYS_STATUS_SENSOR[value] and when performing the operation | we get the value 3 without considering the bitwise operations.

I propose to return not the text, but the value itself.
Or if you want text there will be a method like this:

func label(m MAV_SYS_STATUS_SENSOR) string {
  l := []string{}
  for k, v := range labels_MAV_SYS_STATUS_SENSOR {
   if k&m == k {
    l = append(l, v)
   }
  }
  return fmt.Sprintf("%v", l)
}

Cannot use version v3.0.0

Good day,

I cannot use the latest version v3.0.0 inside my project:

None of the following works:

$ go get github.com/bluenviron/gomavlib/v2
$ go get github.com/bluenviron/gomavlib/v2@latest
$ go get github.com/bluenviron/gomavlib/[email protected]

$ go get -u github.com/bluenviron/gomavlib/v2
$ go get -u github.com/bluenviron/gomavlib/v2@latest
$ go get -u github.com/bluenviron/gomavlib/[email protected]

$ go get -d github.com/bluenviron/gomavlib/v2
$ go get -d github.com/bluenviron/gomavlib/v2@latest
$ go get -d github.com/bluenviron/gomavlib/[email protected]

https://proxy.golang.org/github.com/bluenviron/gomavlib/v2/@v/list does not return v3.0.0.

Neither with GONOPROXY=github.com/bluenviron.

Field index out of range while writing messages

I have an application that needs to route messages between a few endpoints based on some criteria. When I was using older versions of gomavlib it used to work great. But after updating recently, I have started seeing crashes. The routing works fine for some time but the crash occurs randomly in a few seconds.

I have added the crash logs:

panic: reflect: Field index out of range

goroutine 10 [running]:
reflect.Value.Field({0x58bb40?, 0xc0001d56e0?, 0x2c?}, 0x560ca0?)
        /usr/local/go/src/reflect/value.go:1224 +0xb2
github.com/bluenviron/gomavlib/v2/pkg/message.(*ReadWriter).Write(0xc00009cd00, {0x5fe340?, 0xc0001d56e0}, 0x1)
        /home/divyanshu/go/pkg/mod/github.com/bluenviron/gomavlib/[email protected]/pkg/message/readwriter.go:479 +0x22a
github.com/bluenviron/gomavlib/v2.(*Node).encodeMessage(0xc0004d0120, {0x5a4720?, 0xc0002b8db0})
        /home/divyanshu/go/pkg/mod/github.com/bluenviron/gomavlib/[email protected]/node.go:388 +0x24b
github.com/bluenviron/gomavlib/v2.(*Node).run(0xc0004d0120)
        /home/divyanshu/go/pkg/mod/github.com/bluenviron/gomavlib/[email protected]/node.go:280 +0x390
created by github.com/bluenviron/gomavlib/v2.NewNode
        /home/divyanshu/go/pkg/mod/github.com/bluenviron/gomavlib/[email protected]/node.go:242 +0x9f5
exit status 2

dialect-import error raised 'ERR: unable to open: open custommessages.xml: no such file or directory'

Dear contributors,

I want to generate a custom dialect.
following instructions, I've go an error raised like below.

ZenBook:~/workspace/drone.dev/gomavlib/message_definitions/v1.0$ dialect-import custommessages.xml 
definition custommessages.xml
ERR: unable to open: open custommessages.xml: no such file or directory

has anyone got a solution for this error?

Thanks for your reply in advance.

Sincerely,

MOUNT_STATUS is not parsed correctly

Hello,

I'm using ArduPlane 4.2.1, where it seems like Mavlink got some changes that wasn't there in ArduPlane 4.0.
4.2.1 version now sends extended MOUNT_STATUS that includes MountMode. gomavlib can't parse it (shows invalid value). But even worse, it sends corrupted to other participants.

My test environment:
ArduPlane SIM > Mission Planner - Mission Planner reads MOUNT_STATUS just perfect.
ArduPlane SIM > gomavlib > Mission Planner - Mission Planners start complaining about the bad CRC of MOUNT_STATUS.

I'm happy to contribute to fixing it. I just need some guidance on where potentially to look for a problem.

Constant overflows for enum when building for armv7

First of all, I'd like to say that this is a really great library. Awesome work by the developers in making something that this well designed and is easy to use.

I used the dialect-import tool to generate my own dialect that uses common.xml

While building this for armv7 using:
GOOS=linux GOARCH=arm GOARM=7 go build

I got the following errors:

pkg/dialects/custom/enum_hil_sensor_updated_flags.go:41:5: constant 2147483648 overflows HIL_SENSOR_UPDATED_FLAGS
pkg/dialects/custom/enum_mav_sys_status_sensor.go:75:5: constant 2147483648 overflows MAV_SYS_STATUS_SENSOR

This is probably happening because dialect-import defines the enum constants as int over here. HIL_SENSOR_UPDATED_FLAGS are used as uint32_t in messages. This is probably creating problems for arm32 architecture.

Trouble with MessageParamExtRequestList

I'm trying to get the full parameter list over mavlink with

node.WriteMessageAll(&common.MessageParamExtRequestList{
		TargetSystem: d.Sysid,
		TargetComponent: d.CompId,
	})

I think I should receive the list of params as a response but I don't see anything with:

node, err := gomavlib.NewNode(gomavlib.NodeConf{
		Endpoints: []gomavlib.EndpointConf{
			gomavlib.EndpointUDPServer{Address: url},
		},
		Dialect:     common.Dialect,
		OutVersion:  gomavlib.V1, // change to V1 if you're unable to communicate with the target
		OutSystemID: 254,
	})
	if err != nil {
		panic(err)
	}

	defer node.Close()

	for evt := range node.Events() {
		if frm, ok := evt.(*gomavlib.EventFrame); ok {
			switch msg := frm.Message().(type) {
			
			case *common.MessageParamExtValue:
				fmt.Printf("  Param Val: %v\n", msg)

I can see responses from MAV_CMD items with *common.MessageCommandAck but not from the param list.

I didn't see any examples that included parameter requests with responses and was curious if anyone had something.

Thanks for your help!

Int32 param fails but Real32 works

I'm having a problem uploading int32 parameters to a PX4 flight controller. Real32 params work correctly.

  • I can send an int32 param upload message and receive a param value ACK message
  • The value of the ACK matches the value of the upload
  • When I query the flight controller directly, zero uploads correctly but I get huge values for other values (i.e. I upload an integer 1 and the flight controller reports 1065353216).

I tried changing the data type sent to the drone to a uint32 but the flight controller rejects the value because of the type mismatch.

I can upload params successfully with QGroundControl so I'm pretty sure the problem lies somewhere in gomavlib or how I'm using it. If you have any advice where to look I'd appreciate it.

Thanks for your help!

MAVLink XML change to allow exponentiation operator in bitmask flag

FYI We're modifying the MAVLink XSD validation file in ArduPilot/pymavlink#920 to allow a bitmask value to be declared using the Python exponentiation operator.

This makes it easier to immediately visualize which bit is set by a flag, because you can use the syntax

<entry value="2**15" name="BIT15" />

rather than

<entry value="32768" name=" BIT15" />

This is transparent to mavgen because the parser evaluates the number before creating the generated headers. However it may affect other parsers.
We're not updating the XML yet to allow other parsers time to update.

Any concerns, please raise on ArduPilot/pymavlink#920

Commands

I want to use this library for my drone project but i can't figure out on how to create commands. Is it possible to do ?

Read a file and generate mavlink events like a simulation

Hello @aler9:

I used this library for a couple of projects and I really like it.

Now, I was implementing a csv parser to reproduce a drone flight session. I have log files like this this one:

2021-07-14T17:49:48.837,FE, 6, 0, 0, D,FF,BE,    42,mavlink_request_data_stream_t,req_message_rate,4,target_system,0,target_component,0,req_stream_id,3,start_stop,1,,sig ,Len,14,crc16,15714
2021-07-14T17:49:48.869,FE,1C, 0, 0,F0, 1, 1,    1E,mavlink_attitude_t,time_boot_ms,114029,roll,0.04656032,pitch,0.0197014,yaw,2.916162,rollspeed,0.0042041,pitchspeed,-0.00257009,yawspeed,-0.001730594,,sig ,Len,36,crc16,34405
2021-07-14T17:49:48.869,FE,1C, 0, 0,F1, 1, 1,    21,mavlink_global_position_int_t,time_boot_ms,114029,lat,357658398,lon,1274153234,alt,375210,relative_alt,17,vx,-27,vy,-28,vz,12,hdg,16708,,sig ,Len,36,crc16,35248
2021-07-14T17:49:48.874,FE,1F, 0, 0,F2, 1, 1,     1,mavlink_sys_status_t,onboard_control_sensors_present,325188655,onboard_control_sensors_enabled,308411439,onboard_control_sensors_health,326237231,load,160,voltage_battery,23569,current_battery,0,drop_rate_comm,0,errors_comm,0,errors_count1,0,errors_count2,0,errors_count3,0,errors_count4,0,battery_remaining,99,,sig ,Len,39,crc16,10226
2021-07-14T17:49:48.875,FE, 6, 0, 0,F3, 1, 1,    7D,mavlink_power_status_t,Vcc,5112,Vservo,2,flags,3,,sig ,Len,14,crc16,32691
2021-07-14T17:49:48.876,FE, 4, 0, 0,F4, 1, 1,    98,mavlink_meminfo_t,brkval,0,freemem,65535,freemem32,0,,sig ,Len,12,crc16,44665
2021-07-14T17:49:48.877,FE,1A, 0, 0,F5, 1, 1,    3E,mavlink_nav_controller_output_t,nav_roll,2.662952,nav_pitch,1.120603,alt_error,0,aspd_error,0,xtrack_error,0,nav_bearing,167,target_bearing,0,wp_dist,0,,sig ,Len,34,crc16,42532
2021-07-14T17:49:48.877,FE, 2, 0, 0,F6, 1, 1,    2A,mavlink_mission_current_t,seq,0,,sig ,Len,10,crc16,15872
2021-07-14T17:49:48.878,FE,14, 0, 0,F7, 1, 1,    4A,mavlink_vfr_hud_t,airspeed,0.006447488,groundspeed,0.3970219,alt,375.21,climb,-0.1277524,heading,167,throttle,0,,sig ,Len,28,crc16,63070
2021-07-14T17:49:48.878,FE,15, 0, 0,F8, 1, 1,    24,mavlink_servo_output_raw_t,time_usec,114029578,servo1_raw,982,servo2_raw,982,servo3_raw,982,servo4_raw,982,servo5_raw,982,servo6_raw,982,servo7_raw,0,servo8_raw,0,port,0,servo9_raw,0,servo10_raw,0,servo11_raw,0,servo12_raw,0,servo13_raw,0,servo14_raw,0,servo15_raw,0,servo16_raw,0,,sig ,Len,29,crc16,10946
2021-07-14T17:49:48.879,FE,2A, 0, 0,F9, 1, 1,    41,mavlink_rc_channels_t,time_boot_ms,114029,chan1_raw,1494,chan2_raw,1492,chan3_raw,982,chan4_raw,1494,chan5_raw,1299,chan6_raw,1488,chan7_raw,1493,chan8_raw,1486,chan9_raw,1494,chan10_raw,1494,chan11_raw,1494,chan12_raw,1494,chan13_raw,1494,chan14_raw,1494,chan15_raw,1494,chan16_raw,1494,chan17_raw,0,chan18_raw,0,chancount,16,rssi,0,,sig ,Len,50,crc16,42490
2021-07-14T17:49:48.879,FE,16, 0, 0,FA, 1, 1,    23,mavlink_rc_channels_raw_t,time_boot_ms,114029,chan1_raw,1494,chan2_raw,1492,chan3_raw,982,chan4_raw,1494,chan5_raw,1299,chan6_raw,1488,chan7_raw,1493,chan8_raw,1486,port,0,rssi,0,,sig ,Len,30,crc16,50926
2021-07-14T17:49:48.879,FE,1A, 0, 0,FB, 1, 1,    1B,mavlink_raw_imu_t,time_usec,114029629,xacc,48,yacc,-31,zacc,-997,xgyro,15,ygyro,-7,zgyro,-1,xmag,-342,ymag,-1,zmag,337,id,0,temperature,0,,sig ,Len,34,crc16,61209
2021-07-14T17:49:48.880,FE,16, 0, 0,FC, 1, 1,    74,mavlink_scaled_imu2_t,time_boot_ms,114029,xacc,40,yacc,-30,zacc,-997,xgyro,0,ygyro,-2,zgyro,-1,xmag,-302,ymag,-18,zmag,341,temperature,0,,sig ,Len,30,crc16,27531
2021-07-14T17:49:48.880,FE, E, 0, 0,FD, 1, 1,    1D,mavlink_scaled_pressure_t,time_boot_ms,114029,press_abs,970.946,press_diff,0,temperature,3822,temperature_press_diff,0,,sig ,Len,22,crc16,12037
2021-07-14T17:49:48.881,FE,1E, 0, 0,FE, 1, 1,    18,mavlink_gps_raw_int_t,time_usec,113820000,lat,357658394,lon,1274153298,alt,381980,eph,86,epv,132,vel,0,cog,25646,fix_type,3,satellites_visible,14,alt_ellipsoid,0,h_acc,0,v_acc,0,vel_acc,0,hdg_acc,0,yaw,0,,sig ,Len,38,crc16,56474
2021-07-14T17:49:48.882,FE,23, 0, 0,FF, 1, 1,    7C,mavlink_gps2_raw_t,time_usec,113820000,lat,357658428,lon,1274153213,alt,383180,dgps_age,0,eph,86,epv,132,vel,2,cog,31181,fix_type,3,satellites_visible,14,dgps_numch,0,yaw,0,alt_ellipsoid,0,h_acc,0,v_acc,0,vel_acc,0,hdg_acc,0,,sig ,Len,43,crc16,20400
2021-07-14T17:49:48.882,FE, C, 0, 0, 0, 1, 1,     2,mavlink_system_time_t,time_unix_usec,1626252579757269,time_boot_ms,114032,,sig ,Len,20,crc16,39761
2021-07-14T17:49:48.883,FE,1C, 0, 0, 1, 1, 1,    A3,mavlink_ahrs_t,omegaIx,-0.01148541,omegaIy,0.005339885,omegaIz,-0.0001667932,accel_weight,0,renorm_val,0,error_rp,0.003915358,error_yaw,0.003721569,,sig ,Len,36,crc16,12478
2021-07-14T17:49:48.883,FE,18, 0, 0, 2, 1, 1,    B2,mavlink_ahrs2_t,roll,0.02967097,pitch,0.02159006,yaw,2.961208,altitude,0,lat,0,lng,0,,sig ,Len,32,crc16,6036
2021-07-14T17:49:48.883,FE,28, 0, 0, 3, 1, 1,    B6,mavlink_ahrs3_t,roll,0.0465561,pitch,0.01969914,yaw,2.916158,altitude,375.21,lat,357658398,lng,1274153234,v1,0,v2,0,v3,0,v4,0,,sig ,Len,48,crc16,19848
2021-07-14T17:49:48.883,FE, 3, 0, 0, 4, 1, 1,    A5,mavlink_hwstatus_t,Vcc,5111,I2Cerr,0,,sig ,Len,11,crc16,54392
2021-07-14T17:49:48.883,FE,16, 0, 0, 5, 1, 1,    88,mavlink_terrain_report_t,lat,357658398,lon,1274153234,terrain_height,0,current_height,0,spacing,0,pending,504,loaded,112,,sig ,Len,30,crc16,63659
2021-07-14T17:49:48.883,FE, E, 0, 0, 6, 1, 1,    9E,mavlink_mount_status_t,pointing_a,0,pointing_b,-70,pointing_c,-52,target_system,0,target_component,0,,sig ,Len,22,crc16,53991
2021-07-14T17:49:48.884,FE,16, 0, 0, 7, 1, 1,    C1,mavlink_ekf_status_report_t,velocity_variance,0.08776879,pos_horiz_variance,0.02859282,pos_vert_variance,0.023573,compass_variance,0.02226898,terrain_alt_variance,0,flags,831,airspeed_variance,0,,sig ,Len,30,crc16,37206
2021-07-14T17:49:48.884,FE,1C, 0, 0, 8, 1, 1,    20,mavlink_local_position_ned_t,time_boot_ms,114035,x,-0.5938861,y,0.5027716,z,-0.01835009,vx,-0.2745549,vy,-0.2851341,vz,0.1275563,,sig ,Len,36,crc16,35136
2021-07-14T17:49:48.884,FE,20, 0, 0, 9, 1, 1,    F1,mavlink_vibration_t,time_usec,114035034,vibration_x,0.01895511,vibration_y,0.01639727,vibration_z,0.01650113,clipping_0,0,clipping_1,0,clipping_2,0,,sig ,Len,40,crc16,17895
2021-07-14T17:49:48.884,FE,24, 0, 0, A, 1, 1,    93,mavlink_battery_status_t,current_consumed,0,energy_consumed,0,temperature,32767,voltages,,current_battery,0,id,0,battery_function,0,type,0,battery_remaining,99,time_remaining,0,charge_state,0,voltages_ext,,,sig ,Len,44,crc16,27062
2021-07-14T17:49:48.885,FE,1C, 0, 0, B, 1, 1,    1E,mavlink_attitude_t,time_boot_ms,114279,roll,0.04652789,pitch,0.01981729,yaw,2.916214,rollspeed,0.004798831,pitchspeed,-0.002019421,yawspeed,-0.001487666,,sig ,Len,36,crc16,6788
2021-07-14T17:49:48.885,FE,1C, 0, 0, C, 1, 1,    21,mavlink_global_position_int_t,time_boot_ms,114279,lat,357658397,lon,1274153234,alt,375220,relative_alt,21,vx,-27,vy,-28,vz,12,hdg,16708,,sig ,Len,36,crc16,47284
2021-07-14T17:49:48.885,FE,1F, 0, 0, D, 1, 1,     1,mavlink_sys_status_t,onboard_control_sensors_present,325188655,onboard_control_sensors_enabled,308411439,onboard_control_sensors_health,326237231,load,155,voltage_battery,23572,current_battery,0,drop_rate_comm,0,errors_comm,0,errors_count1,0,errors_count2,0,errors_count3,0,errors_count4,0,battery_remaining,99,,sig ,Len,39,crc16,18819
2021-07-14T17:49:48.885,FE, 6, 0, 0, E, 1, 1,    7D,mavlink_power_status_t,Vcc,5107,Vservo,0,flags,3,,sig ,Len,14,crc16,25606
2021-07-14T17:49:48.885,FE, 4, 0, 0, F, 1, 1,    98,mavlink_meminfo_t,brkval,0,freemem,65535,freemem32,0,,sig ,Len,12,crc16,11693
2021-07-14T17:49:48.885,FE,1A, 0, 0,10, 1, 1,    3E,mavlink_nav_controller_output_t,nav_roll,2.66055,nav_pitch,1.128154,alt_error,0,aspd_error,0,xtrack_error,0,nav_bearing,167,target_bearing,0,wp_dist,0,,sig ,Len,34,crc16,11749
2021-07-14T17:49:48.885,FE, 2, 0, 0,11, 1, 1,    2A,mavlink_mission_current_t,seq,0,,sig ,Len,10,crc16,56192
2021-07-14T17:49:48.885,FE,14, 0, 0,12, 1, 1,    4A,mavlink_vfr_hud_t,airspeed,0.009835538,groundspeed,0.3958453,alt,375.22,climb,-0.126612,heading,167,throttle,0,,sig ,Len,28,crc16,52521
2021-07-14T17:49:48.885,FE,15, 0, 0,13, 1, 1,    24,mavlink_servo_output_raw_t,time_usec,114279570,servo1_raw,982,servo2_raw,982,servo3_raw,982,servo4_raw,982,servo5_raw,982,servo6_raw,982,servo7_raw,0,servo8_raw,0,port,0,servo9_raw,0,servo10_raw,0,servo11_raw,0,servo12_raw,0,servo13_raw,0,servo14_raw,0,servo15_raw,0,servo16_raw,0,,sig ,Len,29,crc16,26468
2021-07-14T17:49:48.886,FE,2A, 0, 0,14, 1, 1,    41,mavlink_rc_channels_t,time_boot_ms,114279,chan1_raw,1494,chan2_raw,1492,chan3_raw,982,chan4_raw,1494,chan5_raw,1299,chan6_raw,1488,chan7_raw,1493,chan8_raw,1486,chan9_raw,1494,chan10_raw,1494,chan11_raw,1494,chan12_raw,1494,chan13_raw,1494,chan14_raw,1494,chan15_raw,1494,chan16_raw,1494,chan17_raw,0,chan18_raw,0,chancount,16,rssi,0,,sig ,Len,50,crc16,60861
2021-07-14T17:49:48.886,FE,16, 0, 0,15, 1, 1,    23,mavlink_rc_channels_raw_t,time_boot_ms,114279,chan1_raw,1494,chan2_raw,1492,chan3_raw,982,chan4_raw,1494,chan5_raw,1299,chan6_raw,1488,chan7_raw,1493,chan8_raw,1486,port,0,rssi,0,,sig ,Len,30,crc16,14666
2021-07-14T17:49:48.886,FE,1A, 0, 0,16, 1, 1,    1B,mavlink_raw_imu_t,time_usec,114279615,xacc,48,yacc,-29,zacc,-998,xgyro,16,ygyro,-7,zgyro,-1,xmag,-341,ymag,-1,zmag,338,id,0,temperature,0,,sig ,Len,34,crc16,28862
2021-07-14T17:49:48.886,FE,16, 0, 0,17, 1, 1,    74,mavlink_scaled_imu2_t,time_boot_ms,114279,xacc,43,yacc,-29,zacc,-999,xgyro,-1,ygyro,-2,zgyro,0,xmag,-300,ymag,-23,zmag,341,temperature,0,,sig ,Len,30,crc16,65170
2021-07-14T17:49:48.886,FE, E, 0, 0,18, 1, 1,    1D,mavlink_scaled_pressure_t,time_boot_ms,114279,press_abs,970.9694,press_diff,0,temperature,3822,temperature_press_diff,0,,sig ,Len,22,crc16,37211
2021-07-14T17:49:48.886,FE,1E, 0, 0,19, 1, 1,    18,mavlink_gps_raw_int_t,time_usec,114220000,lat,357658391,lon,1274153298,alt,381980,eph,86,epv,132,vel,2,cog,25646,fix_type,3,satellites_visible,14,alt_ellipsoid,0,h_acc,0,v_acc,0,vel_acc,0,hdg_acc,0,yaw,0,,sig ,Len,38,crc16,36449
2021-07-14T17:49:48.886,FE,23, 0, 0,1A, 1, 1,    7C,mavlink_gps2_raw_t,time_usec,114220000,lat,357658426,lon,1274153210,alt,383150,dgps_age,0,eph,86,epv,132,vel,3,cog,31181,fix_type,3,satellites_visible,14,dgps_numch,0,yaw,0,alt_ellipsoid,0,h_acc,0,v_acc,0,vel_acc,0,hdg_acc,0,,sig ,Len,43,crc16,38274
2021-07-14T17:49:48.886,FE, C, 0, 0,1B, 1, 1,     2,mavlink_system_time_t,time_unix_usec,1626252580007199,time_boot_ms,114281,,sig ,Len,20,crc16,28243
2021-07-14T17:49:48.886,FE,1C, 0, 0,1C, 1, 1,    A3,mavlink_ahrs_t,omegaIx,-0.01150851,omegaIy,0.005350895,omegaIz,-0.0001637726,accel_weight,0,renorm_val,0,error_rp,0.003739818,error_yaw,0.003369438,,sig ,Len,36,crc16,53172
2021-07-14T17:49:48.886,FE,18, 0, 0,1D, 1, 1,    B2,mavlink_ahrs2_t,roll,0.02958553,pitch,0.0215758,yaw,2.961349,altitude,0,lat,0,lng,0,,sig ,Len,32,crc16,64559
2021-07-14T17:49:48.886,FE,28, 0, 0,1E, 1, 1,    B6,mavlink_ahrs3_t,roll,0.04652454,pitch,0.01981941,yaw,2.916214,altitude,375.22,lat,357658397,lng,1274153234,v1,0,v2,0,v3,0,v4,0,,sig ,Len,48,crc16,11276
2021-07-14T17:49:48.887,FE, 3, 0, 0,1F, 1, 1,    A5,mavlink_hwstatus_t,Vcc,5107,I2Cerr,0,,sig ,Len,11,crc16,23168

I was thinking if it could be way to read this file to generate events and "replay" the flight session

// allocate the custom endpoint
	endpoint := NewCustomEndpoint()

	// create a node which
	// - communicates with a custom endpoint
	// - understands ardupilotmega dialect
	// - writes messages with given system id
	node, err := gomavlib.NewNode(gomavlib.NodeConf{
		Endpoints: []gomavlib.EndpointConf{
			gomavlib.EndpointCustom{endpoint},
		},
		Dialect:     ardupilotmega.Dialect,
		OutVersion:  gomavlib.V2, // change to V1 if you're unable to communicate with the target
		OutSystemID: 10,
	})
	if err != nil {
		panic(err)
	}
	defer node.Close()

	// read data from the file and send it to the endpoint 
	endpoint.readChan <- []byte("\xfd\t\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x01\x02\x03\x05\x03\xd9\xd1\x01\x02\x00\x00\x00\x00\x00\x0eG\x04\x0c\xef\x9b")
	// but how can I parse the file?


	// print every message we receive
	for evt := range node.Events() {
		if frm, ok := evt.(*gomavlib.EventFrame); ok {
			fmt.Printf("received: id=%d, %+v\n", frm.Message().GetID(), frm.Message())
		}
	}

Could you give me a hit if is possible to parser a file using your library. If is possible which functions should I use? I think I can use EndpointCustom to create events but what I missing is the normalization of the file to the ingested by the endpoint.

Help on getting telemetry stream

I'm using ArduSub and am creating a stand-alone program to retrieve the depth of the ROV and output it as an NMEA-0183 message. I would like send a PARAM_REQUEST_READ message and receive the stream over UDP.

Looking at the examples I'm not sure if I should connect as a udp-client, or udp-broadcast, since I'd like the stream to be directed rather than broadcast.
I have studied the examples and looked a bit into the source code, but I'm afraid I'm stumped. I have tried to include the message to dialect.Messages, with no success:

msgs := []msg.Message{}
msgs = append(msgs, &common.MessageParamRequestRead{1, 1, "", 6})
dialect := ardupilotmega.Dialect
dialect.Messages = msgs
node, err := gomavlib.NewNode(gomavlib.NodeConf{
    Endpoints: []gomavlib.EndpointConf{
        gomavlib.EndpointUDPBroadcast{
            BroadcastAddress: "192.168.2.255:14550",
            LocalAddress:     ":14550",
        },
    },
    Dialect:                dialect,
    OutVersion:             gomavlib.V2, // change to V1 if you're unable to communicate with the target
    OutSystemID:            10,
    StreamRequestEnable:    true,
    StreamRequestFrequency: 4,
})

Any help would be appreciated. A new example showing this common requirement might be helpful for all.

Access to internal message fields?

What's the correct way to access fields in the EventFrame Message structure?

At the moment (just getting my toes wet ๐Ÿ˜‰), I'm trying a simple approach of switching on the message ID (eg case 0 for the heartbeat), then casting to the matching type for field access. eg:

if frm, ok := evt.(*gomavlib.EventFrame); ok { // <-- from the example code ;)

	if frm.SystemId() != 1 { // Only decode messages from the Ground Control Station

		switch frm.Message().GetId() {
		case 0:
			fmt.Println("Heartbeat from Ground Control Station")
			fmt.Printf("MAVLink version: %d\n", frm.Frame.GetVersion())

			decoded, ok := frm.Message().(*ardupilotmega.MessageHeartbeat)
			if !ok {
				fmt.Println("Didn't get it right ;)")
				syscall.Exit(255)
			}
			fmt.Printf("Decoded MAV type: %v\n", decoded.Type)
			fmt.Printf("Decoded System status: %v\n", decoded.SystemStatus)
			fmt.Printf("Decoded MAVLink version: %d\n", decoded.MavlinkVersion)
		default:
			// ...
		}

Pretty sure I'm doing something obviously silly here though, as the output looks ok for some fields but the MAVLink version field doesn't match the version reported by GetVersion(). eg:

Heartbeat from Ground Control Station
MAVLink version: 1
Decoded MAV type: MAV_TYPE_GCS
Decoded System status: MAV_STATE_ACTIVE
Decoded MAVLink version: 3

The "MAVLink version" and "Decoded MAVLink version" there should match, as they're coming from the same message though accessed in two different ways.

Any ideas?

crash on github.com/aler9/gomavlib/pkg/frame.(*V2Frame).Decode

I'm using this lib to test a px4 UAV, somehow I hit on this crash, two times, no clue yet.

Nov 25 14:57:16 gdcx uavm[208678]: panic: runtime error: slice bounds out of range [:920] with capacity 512
Nov 25 14:57:16 gdcx uavm[208678]: goroutine 1923 [running]:
Nov 25 14:57:16 gdcx uavm[208678]: bufio.(*Reader).Read(0xc0004cfaa0, {0xc0004ae7e0, 0xc0003afe08, 0x44c532})
Nov 25 14:57:16 gdcx uavm[208678]:         /usr/local/go/src/bufio/bufio.go:238 +0x2ed
Nov 25 14:57:16 gdcx uavm[208678]: io.ReadAtLeast({0xd07100, 0xc0004cfaa0}, {0xc0004ae7e0, 0x20, 0x20}, 0x20)
Nov 25 14:57:16 gdcx uavm[208678]:         /usr/local/go/src/io/io.go:328 +0x9a
Nov 25 14:57:16 gdcx uavm[208678]: io.ReadFull(...)
Nov 25 14:57:16 gdcx uavm[208678]:         /usr/local/go/src/io/io.go:347
Nov 25 14:57:16 gdcx uavm[208678]: github.com/aler9/gomavlib/pkg/frame.(*V2Frame).Decode(0xc00031c600, 0x3)
Nov 25 14:57:16 gdcx uavm[208678]:         /Users/liuzhiping/go/pkg/mod/github.com/aler9/[email protected]/pkg/frame/v2.go:141 +0x1f3
Nov 25 14:57:16 gdcx uavm[208678]: github.com/aler9/gomavlib/pkg/transceiver.(*Transceiver).Read(0xc000678b80)
Nov 25 14:57:16 gdcx uavm[208678]:         /Users/liuzhiping/go/pkg/mod/github.com/aler9/[email protected]/pkg/transceiver/transceiver.go:130 +0x79
Nov 25 14:57:16 gdcx uavm[208678]: github.com/aler9/gomavlib.(*Channel).run.func1()
Nov 25 14:57:16 gdcx uavm[208678]:         /Users/liuzhiping/go/pkg/mod/github.com/aler9/[email protected]/channel.go:93 +0xbc
Nov 25 14:57:16 gdcx uavm[208678]: created by github.com/aler9/gomavlib.(*Channel).run
Nov 25 14:57:16 gdcx uavm[208678]:         /Users/liuzhiping/go/pkg/mod/github.com/aler9/[email protected]/channel.go:85 +0xef

go version: 1.17

send MAV_CMD

hi, this might be a really silly question but I am trying to use golang to communicate with SITL at TCP port 5760 (docker). With gomavlib provided examples, I can pick up the mavlink message (heartbeat, battery, etc) from sitl, but I was wondering how I could send out MAV_CMD to sitl to instruct it to do certain tasks; commands such as
MAV_CMD_NAV_WAYPOINT
MAV_CMD_NAV_RETURN_TO_LAUNCH
MAV_CMD_NAV_TAKEOFF
MAV_CMD_NAV_LAND
I am very new to mavlink, any advice would be really appreciated!

How to parse MessageRaw struct.

Question, how is it recommended to parse MessageRaw struct without knowledge of the version?

Recent Change
596af81#diff-f6846c341ab11ff34eeb7463ce2816ff

Code

	var fault error
	state.peer, fault = gomavlib.NewNode(gomavlib.NodeConf{
		OutSystemId:      255,
		HeartbeatDisable: true,
		Endpoints:        []gomavlib.EndpointConf{endpoint},
	})
	exitOnError(peerConnectionFailed, fault)
	defer state.peer.Close()

Output

OutVersion not provided

Use of custom dialect makes node.Close() hang

Hi,

I am using 3DR SiK radios. I am noticing weird behavior when using custom dialects. After the program finishes, when I try to close the nodes, the call to node.Close hangs.

I provide an example of what I am talking about. When using the custom dialect (taken from the library examples), after sending 5 messages the program hangs on the close calls. When using the ardupilotmega one, it doesn't.

package main

import (
	"fmt"
	"log"
	"sync"
	"time"

	"github.com/bluenviron/gomavlib/v3"
	"github.com/bluenviron/gomavlib/v3/pkg/dialect"
	"github.com/bluenviron/gomavlib/v3/pkg/dialects/ardupilotmega"
	"github.com/bluenviron/gomavlib/v3/pkg/message"
)

type MessageCustom struct {
	Param1 uint8
	Param2 uint8
	Param3 uint32
}

func (*MessageCustom) GetID() uint32 {
	return 22
}

var (
	myDialect = &dialect.Dialect{
		Version: 3,
		Messages: []message.Message{
			&MessageCustom{},
		},
	}
)

func main() {
	// Select between custom dialect or ardupilotmega
	custom := true

	var dialect *dialect.Dialect
	if custom {
		dialect = myDialect
	} else {
		dialect = ardupilotmega.Dialect
	}

	senderNode, err := gomavlib.NewNode(gomavlib.NodeConf{
		Endpoints: []gomavlib.EndpointConf{
			gomavlib.EndpointSerial{
				Device: "/dev/ttyUSB4",
				Baud:   57600,
			},
		},
		Dialect:     dialect,
		OutVersion:  gomavlib.V2,
		OutSystemID: 10,
	})
	if err != nil {
		log.Fatal("Creating receiver node")
	}
	defer senderNode.Close()

	receiverNode, err := gomavlib.NewNode(gomavlib.NodeConf{
		Endpoints: []gomavlib.EndpointConf{
			gomavlib.EndpointSerial{
				Device: "/dev/ttyUSB5",
				Baud:   57600,
			},
		},
		Dialect:     dialect,
		OutVersion:  gomavlib.V2,
		OutSystemID: 11,
	})
	if err != nil {
		log.Fatal("Creating receiver node")
	}
	defer receiverNode.Close()

	done := make(chan struct{})
	var wg sync.WaitGroup
	wg.Add(2)
	go func() {
	loop:
		for {
			select {
			case evt := <-senderNode.Events():
				if frm, ok := evt.(*gomavlib.EventFrame); ok {
					fmt.Printf("[TX-RX] %T\n", frm.Message())
				}
			case <-done:
				break loop
			}
		}
		wg.Done()
	}()
	go func() {
	loop:
		for {
			select {
			case evt := <-receiverNode.Events():
				if frm, ok := evt.(*gomavlib.EventFrame); ok {
					fmt.Printf("[RX] id=%d, %+v\n", frm.Message().GetID(), frm.Message())
				}
			case <-done:
				break loop
			}
		}
		wg.Done()
	}()

	for range 5 {
		if custom {
			senderNode.WriteMessageAll(&MessageCustom{
				Param1: 1,
				Param2: 2,
				Param3: 3,
			})
		} else {
			senderNode.WriteMessageAll(&ardupilotmega.MessageParamValue{
				ParamId:    "test_parameter",
				ParamValue: 123456,
				ParamType:  ardupilotmega.MAV_PARAM_TYPE_UINT32,
				ParamCount: 1,
				ParamIndex: 1,
			})
		}
		time.Sleep(time.Second)
	}

	fmt.Println("CLOSING channel")
	close(done)
	wg.Wait()
	fmt.Println("GOODBYE")
}

EDIT: When I first opened the issue I thought this was caused by opening two nodes from a single process, but after further testing I noticed the issue only happened when using a custom dialect.

Bitmask enums conversion from string

The unmarshaling of bitmask enum seems to be incomplete: for example in the case of common.POSITION_TARGET_TYPEMASK

// UnmarshalText implements the encoding.TextUnmarshaler interface.
func (e *POSITION_TARGET_TYPEMASK) UnmarshalText(text []byte) error {
	labels := strings.Split(string(text), " | ")
	var mask POSITION_TARGET_TYPEMASK
	for _, label := range labels {
		if value, ok := values_POSITION_TARGET_TYPEMASK[label]; ok {
			mask |= value
		} else if value, err := strconv.Atoi(label); err == nil {
			mask |= POSITION_TARGET_TYPEMASK(value)
		} else {
			return fmt.Errorf("invalid label '%s'", label)
		}
	}
        //missing statement here:
        //       *e=mask
	return nil
}

the statement *e=mask before return nil is missing. Without this statement there is no conversion from string. The correction should be reported in conversion.go.

No error generated for failed client connections.

The following example will fail to reach the TCP Client endpoint, if none exists, and will forever wait on node.Events(). There appears to be no way of detecting the failure, is this by design?

	node, err := gomavlib.NewNode(gomavlib.NodeConf{
		Endpoints: []gomavlib.EndpointConf{
			gomavlib.EndpointTcpClient{"127.0.0.1:5600"},
		},
		Dialect:     ardupilotmega.Dialect,
		OutSystemId: 10,
	})
	if err != nil {
		panic(err)
	}
	defer node.Close()

	for evt := range node.Events() {
		if frm, ok := evt.(*gomavlib.EventFrame); ok {
			fmt.Printf("received: id=%d, %+v\n", frm.Message().GetId(), frm.Message())
		}
	}

Thanks for the library ๐Ÿ‘

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.