0

我如何使用现有的非 subnero 与 UnetStack 的调制解调器(基本上不支持 UnetStack)?我详细阅读了这篇文章,但不幸的是编译问题很糟糕。谁能指出我正确的方向?

以下是我遇到的详细错误:

BUG! exception in phase 'semantic analysis' in source unit 'Script66.groovy' The lookup for MyModemDriver caused a failed compilation. There should not have been any compilation from this call.

这是我的代码:

import org.arl.fjage.*
import org.arl.unet.*
import com.fazecast.jSerialComm.*
import org.arl.unet.api.UnetSocket
import org.arl.unet.phy.RxFrameNtf
import org.arl.unet.phy.TxFrameNtf


class PopotoModemDriver extends UnetAgent {

    // Using UnetSocket to connect to network modem ('ip',port)
    def sock = UnetSocket('192.168.0.42', 1100)
    AgentID notify      // notification topic
    int plvl = 170      // default power level setting

    @Override
    void setup() {
        notify = topic()
        register Services.PHYSICAL
        register Services.DATAGRAM
    }


    @Override
    void shutdown() {
        sock.close()
    }

    @Override
    Message processRequest(Message req) {
        if (req instanceof DatagramReq) {
            String s = "AT+TX:" + req.to + "," + req.data.encodeHex() + "\n"
            byte[] b = s.getBytes()
            sock.writeBytes(b, b.length)
            add new OneShotBehavior({
                send new TxFrameNtf(req)
            })
            return new Message(req, Performative.AGREE)
        }
        return null
    }

    int getMTU() {
        return 32         // frame size
    }

    boolean getRxEnable() {
        return true
    }

    float getPropagationSpeed() {
        return 1500       // assume sound speed is 1500 m/s
    }

    int getTimestampedTxDelay() {
        return 0          // our modem doesn't support timestamped transmissions
    }

    long getTime() {
        return 1000*System.currentTimeMillis()    // use system clock for timing in µs
    }

    boolean getBusy() {
        return false
    }

    float getRefPowerLevel() {
        return 0          // our modem uses absolute power levels in dB re uPa @ 1m
    }

    float getMaxPowerLevel() {
        return 180        // our modem can transmit at max power level of 180 dB
    }

    float getMinPowerLevel() {
        return 120        // ... and a min power level of 120 dB
    }

    int getMTU(int ch) {
        return 32         // frame size
    }

    float getFrameDuration(int ch) {
        return getMTU(ch)/getDataRate(ch)
    }

    float getPowerLevel(int ch) {
        return plvl
    }

    int getErrorDetection(int ch) {
        return 0
    }

    int getFrameLength(int ch) {
        return getMTU(ch)   // fixed frame size
    }

    int getMaxFrameLength(int ch) {
        return getMTU(ch)   // fixed frame size
    }

    int getFec(int ch) {
        return 0
    }

    List getFecList(int ch) {
        return null
    }

    float getDataRate(int ch) {
        return 320.0      // data rate of 320 bps
    }

    float setPowerLevel(int ch, float x) {
        plvl = x
        if (plvl < getMinPowerLevel()) plvl = getMinPowerLevel()
        if (plvl > getMaxPowerLevel()) plvl = getMaxPowerLevel()
        String s = "AT+TPL:" + plvl + "\n"
        byte[] b = s.getBytes()
        sock.writeBytes(b, b.length)
        return plvl
    }


    @Override
    void startup() {
        sock.openPort()
        add new CyclicBehavior({
            int n = sock.bytesAvailable()
            if (n == 0) Thread.sleep(20)
            else {
                // data available
                byte[] buf = new byte[n]
                sock.readBytes(buf, n)
                parseRxData(new String(buf))
            }
        })
    }

    String data = ''

    void parseRxData(String s) {
        data += s
        int n = data.indexOf('\n')
        if (n < 0) return
        s = data.substring(0, n)
        data = data.substring(n)
        if (s.startsWith("AT+RX:")) {
            int addr = s.substring(6,9) as int
            byte[] bytes = s.substring(10).decodeHex()
            send new RxFrameNtf(
                    recipient: notify,
                    from: addr,
                    data: bytes,
                    bits: 8*bytes.length,
                    rxTime: 1000*System.currentTimeMillis()
            )
        }
    }


}
4

1 回答 1

2

@manuignatius 是对的,当动态加载的 Groovy 类中存在语法错误时,Groovy 会抱怨这一点。

要获得有关错误的更详细的堆栈跟踪,您可以手动调用 Groovy 编译器。设置CLASSPATH环境变量以包含lib本地 UnetStack 安装文件夹中的所有 jar。然后简单地运行groovyc MyModemDriver.groovy,它应该会显示编译错误(如果有)。.class然后可以将成功编译生成的编译文件复制到classesUnetStack/modem 中的文件夹而不是源代码。

于 2020-11-24T02:21:05.480 回答