V-REP 的 Lua `tonumber` returns 无 Linux

V-REP's Lua `tonumber` returns nil on Linux

我们开发了一个简单的V-REP simulation that works pretty well on OS X but not on Linux (Ubuntu 15.04). Lua被用作主要的脚本语言。

我们附上以下代码(注释中有 return 值)不幸的是 returns nil on Linux(但将 e[3] 转换为OS X 上没有问题的号码):

e[3]                   -- -0.677782532263
type(e[3])             -- string
type(tonumber(e[3]))   -- nil

真正有趣的是,之前的代码在 Lua 5.2.3 控制台(OS X 和 Linux 中的工作方式与预期的一样。但是,当 Linux 上的 运行 时,V-REP 无法将字符串正确转换为数字。

我们尝试了两个 32b and 64b V-REP versions(今天下载),结果完全相同 - nils。你能指出一些我们遗漏的东西吗? Lua 和 V-REP 都不是我们每天使用的工具。

编辑 1: 我使用 Ubuntu 15.04。 V-REP 使用 Lua 5.1,我的 Lua 版本:

$ apt-cache policy lua5.1
lua5.1:
  Installed: 5.1.5-7.1
  Candidate: 5.1.5-7.1
  Version table:
 *** 5.1.5-7.1 0
        500 http://cz.archive.ubuntu.com/ubuntu/ vivid/main amd64 Packages
        100 /var/lib/dpkg/status

在控制台中,我尝试了以下操作:

$ lua
Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
> e={[3]="-0.677782532263"}; print(e[3], type(e[3]), tonumber(e[3]), type(tonumber(e[3])))
-0.677782532263 string  -0.677782532263 number

套餐

错误是因为V-REP使用Lua5.1,以及我们测试的电脑on 有不同的数字语言环境(linux 有 LC_NUMERIC=cs_CZ.UTF-8 而 mac 可能有 en_US)。

这意味着 Lua 在 Mac 上将字符串中的浮点数识别为数字,但是 Lua 在 Linux 上使用不同的语言环境却没有 - 它没有'没有 逗号(例如 -3,513)作为区域设置所需的小数点分隔符,因此它返回 nil 进行转换。

修复方法是在 运行 vrep 之前将 LC_NUMERIC 标志设置为 en_US 语言环境,如下所示:

...$ LC_NUMERIC=en_US.UTF-8 ./vrep

这将强制区域设置为基于点的,并使 Lua 能够识别数字。

感谢@Etan 的所有帮助以及从正确的方向解决问题。

另一种从 lua 代码设置语言环境的方法 os.setlocale("C")

并非所有系统都可以在启动时更改任意应用程序的区域设置,有时需要更改整个系统的区域设置,这对其他应用程序来说可能很不方便。如果使用 V-REP 分发的脚本以与 XML 文件相同的方式分发,其中分隔符是句号而不是逗号,那么在调用 tonumber 函数之前,正确的控制台应该是合乎逻辑的通过开放环境的变量从 LUA 而不是外部安装。

LUA文档中清楚地描述了os.setLocale函数的作用,并且明确说明影响字符串到数字的转换。并提示在调用转换函数前需要确认设置是否正确

此外,在内部更改语言环境的脚本更易于移植,因为不需要启动人员知道应该从外部为 V-REP 指定哪些环境变量。