×

Alexa控制的乐高生物实验

消耗积分:0 | 格式:zip | 大小:0.00 MB | 2023-06-19

分享资料个

描述

Alexa 控制的乐高生物实验

背景

空间。最后的边界。在 NASA 准备重返月球之际,国际空间站在过去 20 年中一直以 17, 000 英里/小时的速度飞越天空,进行了数不清的科学研究,造福了地球上的我们。这项研究的一个关键主题是研究微重力下生命的行为,包括人类水平和微观尺度。当人类梦想在其他星球上定居时,我们必须首先严格了解生物有机体如何在微重力下运作。一些在地球上相对无害的病原体在微重力环境下会变得危险吗?人造器官可以在失重环境中生长和制造吗?空间究竟如何改变细胞的功能?哪些医学进步可以拯救地球上的生命?

太空实验很昂贵。一名宇航员的时间价值每小时 60, 000 到 80, 000 美元。许多宇航员本身并不是科学家,而是工程师和飞行员。他们接受了广泛的实验培训和指导程序,但基础科学往往不是他们的母语学科。

此外,未来的火星任务可能会发现它们离地球太远,无法与任务控制中心进行实时交互以帮助运行或进行实验。如果是这种情况,工作人员必须自给自足,并获得进行实验所需的帮助。

问题陈述

由于在低地球轨道 (LEO) 和长时间的行星际飞行期间运行和监测微重力实验的复杂性,宇航员需要一种与实验交互的直观方法,从而消除对特定科学领域的利基知识的需求,并促进简单的互动与最少的培训。

解决方案概述

为解决此解决方案,我制作了 ALBERT 或 Alexa 控制的 LEGO Biological ExpeRimenT 原型。ALBERT 展示了语音控制实验界面的有效性,该界面允许宇航员在没有与任务控制持续通信且无需大量培训的情况下直观地与系统交互。

pYYBAGOIL0KAJJa5AAwQ5plIByM310.jpg

在目前的形式下,ALBERT 能够对语音命令做出反应,以创建新的细菌生长实验、选择、擦拭、储存和监测琼脂平板。宇航员只需要插入一根棉签并说:“Alexa,使用这个棉签。” 要检查实验,机组人员可以简单地问,“Alexa,检查板 1”。鉴于 ALBERT 是由乐高材料制成的,它确实尝试了一些成功的可变性,但是,它反复能够创建和存储盘子。

直观语音控制的重要性

ALBERT 直观的语音控制界面对其主要目标至关重要——简化复杂实验的界面,使几乎未经训练的机组人员能够快速、熟练地创建和监控科学研究。当前工作的扩展将允许与多个实验进行动态语音交互,图像处理和数据记录的集成,以及从发射到着陆的整个实验过程的关键简化。

为什么选择 Alexa?

Alexa 是 ALBERT 的完美语音输入方法。通过意图对命令进行分类,Alexa 理解话语背后目的的能力优于简单的语音识别系统。此外,Alexa 与许多其他工具和系统集成的能力为其用作具有直观交互的复杂系统(例如轨道实验室或航天器)的统一自然语言界面打开了大门。

应用

与为太空探索开发的许多其他技术一样,ALBERT 的影响可以远远超出国际空间站或行星际飞行器。潜在的其他应用包括:

地球上的自动化实验室(像这样)

展示将实验室与语音助手(如 Alexa)集成以实现统一的人机实验室或乘员车辆界面的价值

促进可以利用新的深度学习和人工智能技术的全自动实验监控工具的开发

设计问题

在构建 ALBERT 原型时,遇到了几个关键的设计问题。此处简要总结了它们以及所选的解决方案。

刚架

项目开始时的一个关键问题是确保必要部分(工作站、机械臂、无菌板存储和现场实验存储)的仔细定位。这些组件之间的错位会对程序的可靠性和可重复性产生负面影响。

为了缓解这种情况,所有关键模型都固定在铝制 TETRIX 框架上。

pYYBAGOIL0aAZfuRAAI7iPMs0jQ830.png

铝制 TETRIX 底座

可靠的板定位

乐高齿轮系经常会经历大量的活动,使得非常精确的定位变得非常困难。然而,盘子必须始终放置在工作站上的狭窄区域,以使手臂能够可靠地抬起和更换盖子。此外,垂直存储架几乎没有水平位置误差的余地。

通过将轴作为导轨放置在工作站转盘的底部,我可以确保即使在出现水平操纵器错误的情况下,也能将盘子向下引导到转盘中。为确保印版能够始终如一地垂直存放,机架设计中包含了倾斜的导轨。

擦拭盘子

要制作实验板,拭子不能简单地接触琼脂,而必须在一定面积的表面上擦拭。

我没有需要第二个机械臂来在琼脂表面上操纵棉签,而是选择直接旋转培养皿以在其表面上划出弧线。只需将带有橡胶轮胎的电机连接到工作站,即可轻松旋转盘子,无需复杂的组装。

pYYBAGOIL0mAA4IoAAHHdd2rKmQ231.png

旋转盘子的橡胶轮

控制两个子系统

为了限制复杂性,ALBERT 分为两个主要子系统:机械臂和工作站。ALBERT 的主控制器 EV3 智能程序块必须能够与工作站通信以触发擦拭和监控操作。

ev3dev 操作系统使 EV3 能够使用nxt-python库通过 USB 连接远程控制 NXT。

两位夹持器/手腕

要垂直存放板并将它们水平放置在工作站中,需要两个手臂位置,水平和垂直。

腕关节可以实现这种旋转,但必须注意将腕关节旋转轴与末端执行器的中心对齐。未对准会导致水平和垂直夹持器方向彼此略微偏移,从而在放置板或取下盖子时引起问题。

poYBAGOIL0yAF7ftAAHzHrEckhA692.png

手腕机构

可重复的基本位置

手臂必须能够在无菌架、工作站和存储架上重复定位。最初,这是通过航位推算完成的,但为了提高性能,EV3 颜色传感器用于检测手臂底座旋转时的彩色条纹。

poYBAGOIL0-AVxtpAAHW4-uGlQ0497.png

使用彩色胶带作为关键点标记

提起培养皿盖

提起盘盖很困难。在我的估计中,公差只有大约 +/- 0.25 厘米,这是很难用乐高齿轮实现的。虽然 ALBERT 几次抓住边缘都能掀开盖子,但并不一致。盖子通常会在夹具中转动,防止它被重新装回盘子上,或者完全滑出夹具。

解决办法是稍微修改一下盘子的盖子,增加一个“把手”,抓手可以很容易地抓住它。这个手柄由两个锥齿轮制成,并用热胶粘在盘盖上。

poYBAGOIL3OAUUN7AA4Kcxsj0ig465.jpg

原型管道胶带手柄和最终的热粘锥齿轮手柄

软件架构

软件堆栈分为两个主要部分:Alexa 托管的 Node.js 技能和 EV3 上的 Python Alexa Gadget 代码。

Alexa 技能

Alexa技能代码可在技能目录中浏览。遵循 LEGO MINDSTORMS Alexa 挑战的示例任务模式,定义并实施了几个关键意图。

MakePlateIntent - 此意图将“制作盘子”指令发送到 EV3 小工具

CheckPlateIntent - 此意图将“检查车牌”指令连同要检查的车牌号一起发送到 EV3 小工具。在大多数情况下,这将是一个,但将来会扩展到具有多个存储架的设备。

GadgetEventHandler - 此处理程序捕获从 EV3 小工具返回的事件,以报告板材何时制作或先前制作的板材的状态。

EV3 Python 小工具代码

小工具代码旨在从基于云的 Alexa 技能接收小工具命令并激活 ALBERT。这包括一个将 ALBERT 的功能封装在albert.py中的类和一个基于示例代码的小工具类,在albert_gadget.py中编写。小工具代码与用作起点的示例任务非常相似。ALBERT 控制代码广泛使用为操纵器(手臂)定义的关键点,以简洁地编码每项任务所需的运动序列。然后可以从小工具代码触发这些任务。主要的小工具事件处理程序很简单,处理 Alexa 指令并根据任务生成事件。

 

def on_custom_mindstorms_gadget_control(self, directive):
    try:
        payload = json.loads(directive.payload.decode("utf-8"))
        print("Control payload: {}".format(payload), file=sys.stderr)
        control_type = payload["type"]
        if control_type == "make_plate":
            # make the plate
            self.albert.make_plate()
            self.plate_counter += 1
            self.send_custom_event('Custom.Mindstorms.Gadget', 'plate_finished', {
                'plate_number': self.plate_counter
            })
        elif control_type == "check_plate":
        # check the plate
        # will need plate number
        number = int(payload["plate_number"])
        if number > self.plate_counter:
            self.send_custom_event('Custom.Mindstorms.Gadget', 'plate_status', {
                'plate_number': -1
            })
        else:
            refl = self.albert.check_plate()
            self.send_custom_event('Custom.Mindstorms.Gadget', 'plate_status', {
                'plate_number': number,
                'reflectivity': round(refl, 2)
            })
    except KeyError:
        print("Missing expected parameters: {}".format(directive), file=sys.stderr)

 

这是albert.py中的一段代码,用于使用颜色传感器对齐底座。注意最后的旋转,将传感器从彩色胶带的边缘移动到中心。这可确保底座在从任一方向旋转时都停在正确的位置。

 

def rotate_base(self, color):
    '''
    Rotate from one color indicator to another.
    Color order is:
    YELLOW <--> BLUE   <--> RED
    STORE  <--> STATION <--> STERILE
    '''
    current_color = self.color_sensor.color
    if current_color == color:
        return
    direction = 1
    if (current_color == STATION_COLOR and color == STERILE_COLOR) or current_color == STORE_COLOR:
        direction = -1
    self.arm_base.on(SPEEDS[0]*direction, block=False)
    while self.color_sensor.color != color:
        pass
    self.arm_base.stop()
    self.arm_base.on_for_rotations(SPEEDS[0], direction*STRIPE_BIAS)

 

连同将肩膀和手腕移动到关键点的功能,这使我们可以编写如下程序功能:

 

def get_plate(self, from_storage=False, upside_down=False):
    '''
    Sequence to get a plate and place it in the workstation.
    Post-conditions
    Gripper: WIDE
    Arm:     DOWN
    Base:    STATION
    '''
    src = STORE_COLOR if from_storage else STERILE_COLOR
    self.move_to_keypoint(KP_UP_HORZ)
    self.rotate_base(src)
    self.set_gripper(GRIP_NARROW)
    self.move_to_keypoint(KP_DOWN_HORZ)
    self.set_gripper(GRIP_CLOSED)
    self.move_to_keypoint(KP_UP_HORZ)
    self.rotate_base(STATION_COLOR)
    dest_up = KP_UP_VERT_INVERT if upside_down else KP_UP_VERT
    dest_down = KP_DOWN_VERT_INVERT if upside_down else KP_DOWN_VERT
    self.move_to_keypoint(dest_up)
    self.move_to_keypoint(dest_down)
    self.set_gripper(GRIP_WIDE)
    self.move_to_keypoint(KP_DOWN_HORZ)

 

可以进一步调用这些来执行完整的任务:

 

def make_plate(self):
    ''' Sequence to make a plate. '''
    self.get_plate()
    self.lift_lid()
    self.swab_plate()
    self.lower_lid()
    self.store_plate()

 

一些支持函数支持检查印版时使用的附加参数:

 

def check_plate(self):
    ''' Sequence to check plate. '''
    self.get_plate(from_storage=True, upside_down=True)
    self.move_to_keypoint(KP_UP_HORZ)
    refl = self.station.check_status()
    self.move_to_keypoint(KP_DOWN_HORZ)
    self.store_plate(is_upside_down=True)
    return refl

 

workstation.py文件利用nxt-python库通过USB 连接远程控制 NXT。首先,我们可以设置工作站连接:

 

self.brick = nxt.locator.find_one_brick(method=nxt.locator.Method(bluetooth=False))
self.color = Color20(self.brick, PORT_4)
self.tilt_motor = Motor(self.brick, PORT_B)
self.rotate_motor = Motor(self.brick, PORT_C)

 

拭子和检查板操作简单,将头部移动到位并在必要时旋转培养皿。擦拭功能如下所示:

 

def swab(self):
    self.tilt_motor.turn(TILT_MOTOR_POWER, TILT_DEGREES)
    self.rotate_motor.turn(ROTATE_MOTOR_POWER,PLATE_ROTATION_DEGREES)
    self.tilt_motor.turn(-TILT_MOTOR_POWER, TILT_DEGREES)

 

所有代码都封装在类中,方便维护。

建立你自己的

所有 CAD 模型都是使用Studio创建的。为简洁起见,省略了分步构建说明,因为您构建的 ALBERT 可能具有不同的外形或实验设计。

1. 构建手臂

pYYBAGOIQmeAQeneAAcmSuG0ARg237.png

附上手臂 CAD 模型以了解有关构建手臂的详细信息。

2.搭建工作站

pYYBAGOIQnyAO7PcAAdYLLXtNMs045.png

使用附加的workstation.io文件构建工作站。

3. 构建 TETRIX 底座和板架

pYYBAGOIQomAKvk3AAR1mIyLpVU814.png

使用plate_holder.io构建两个板架(镜像)。

为了创建带有彩色条纹的平台,我使用了一段泡沫芯板。将手臂与每个无菌架、工作站和存储架对齐,并分别在传感器下方放置一条红色、蓝色和黄色胶带。

4. 设置软件环境

1. 从下载页面下载 ev3dev 。

2. 使用Etcher将映像刷入 SD 卡。

3. 使用 USB A-to-Mini-B 电缆将 EV3 程序块连接到您的计算机并启用 USB 互联网共享。

4. 在您​​的计算机上,安装Microsoft 的Visual Studio Code 。

5. 安装后,打开扩展面板 ( Ctrl+Shift+X )。然后搜索并安装ev3dev-browser扩展。

6. 在您的计算机上,从GitHub存储库下载源代码。如果您不熟悉 git,只需使用本页右上角的按钮将代码下载为 zip 文件。高级用户可以克隆存储库。

7. 为了与 NXT 工作站通信,nxt-python必须安装在 EV3 (不是你的电脑)上。为此,您需要在 EV3 程序块终端中运行一些命令。

要访问此终端,请展开资源管理器面板底部的“ev3dev 设备浏览器”组 ( Ctrl+Shift+E ) 并通过单击“单击此处连接设备”连接到您的程序块。

连接后,右键单击 ev3dev 设备并选择“打开 SSH 终端”。

在终端中运行以下命令(您可以忽略以“#”开头的行;这些是注释)

 

# install pip3 (python3 package manager)
sudo apt install python3-pip

# install pyusb for USB connection to NXT
sudo pip3 install pyusb

# install nxt-python (python3 beta)
wget https://github.com/ev3dev/nxt-python/archive/ev3dev-stretch.zip
unzip ev3dev-stretch
cd nxt-python-ev3dev-stretch
python3 setup.py install # you may need to prepend `sudo`

 

5. 设置 Alexa 小工具

(这些步骤改编自LEGO MINDSTORMS 语音挑战任务 1示例)

1.如果您还没有亚马逊开发者账户,请创建一个

2. 进入Alexa语音服务页面,点击“产品”按钮。

3. 点击页面右上角的“创建产品”按钮。

4. 将产品命名为“MINDSTORMS EV3”,ID 为“EV3_01”。产品类型可以是“Alexa Gadget”,类别是“Animatronic or Figure”。填写说明,如果打算进行商业分发,则选择“否”,如果是儿童产品,则选择“否”。点击完成产品创建。

5. 在控制台的设备列表中单击您的新设备。

6. 在产品页面上,记下 Amazon ID 和 Alexa Gadget Secret 代码。稍后您将需要它们。

6. 编写 Alexa 技能

(这些步骤改编自LEGO MINDSTORMS 语音挑战任务 3示例。)

1. 转到Alexa Developer Console ,然后单击页面右侧的蓝色“Create Skill”按钮。

2. 将技能命名为“ALBERT”并使用默认选择的“Custom”模型。在页面底部,选择“Alexa-Hosted (Node.js)”。完成点击技能创建页面。

3. 通过在左侧菜单中选择“Interfaces”并打开“Custom Interface Controller”来启用自定义界面控制器。使用页面顶部的按钮保存更新。

4. 接下来,通过单击左侧菜单中的“JSON 编辑器”项(在“交互模型”标题下)设置交互模型,然后从ALBERT 源代码的技能文件夹中拖放model.json文件。使用页面顶部的按钮保存并构建模型。

5. 单击屏幕顶部的“代码”选项卡。创建以下文件并将相应 ALBERT 源文件中的内容复制并粘贴到skill/lambda目录中。

common.js - 常见的意图处理,例如寻求帮助或取消操作(来自 Mission 3)

index.js - 包含主要意图和事件处理程序

package.json - 包信息

util.js - 实用程序代码(来自 Mission 3)

6.点击“保存”,然后点击“部署”来激活你的技能!

7. 在gadget目录下创建albert_gadget.ini文件,内容如下:

 

[GadgetSettings]
amazonId = YOUR_GADGET_AMAZON_ID
alexaGadgetSecret = YOUR_GADGET_SECRET
[GadgetCapabilities]
Custom.Mindstorms.Gadget = 1.0

 

ID 和 secret 是第 5 步中的值。

7. 下载运行

差不多好了!在 VS Code 资源管理器面板 ( Ctrl+Shift+E ) 中,在屏幕底部找到 ev3dev 设备。单击 ev3dev 设备浏览器标题左边缘附近的下载按钮。

如果您没有看到此按钮,请确保您已连接到您的 EV3 程序块

复制文件后,找到albert/gadget/albert_gadget.py文件,右键单击它,然后选择“运行”。

如果这是您第一次跑步,您需要通过蓝牙将 EV3 与您的 Alexa 设备配对。您可以通过 Alexa 应用程序执行此操作。确保 EV3 的蓝牙已打开。

如果您遇到蓝牙在 EV3 上不可用的问题,请参阅此 Github 问题。TL;DR:在您的 EV3 终端(安装nxt-python 的同一终端)上运行这些行

 

sudo systemctl mask systemd-rfkill.service
sudo systemctl mask systemd-rfkill.socket

 

然后重启你的 EV3。

关于我

嘿!我是 Matthew,我正在攻读机器学习博士学位。在肯塔基大学,10 多年前通过 NXT 首次与 LEGO MINDSTORMS 合作。在我的博客https://mruss.dev上更多地了解我。

---

这些说明截至 2019 年 12 月 25 日是最新的。

 

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

评论(0)
发评论

下载排行榜

全部0条评论

快来发表一下你的评论吧 !

'+ '

'+ '

'+ ''+ '
'+ ''+ ''+ '
'+ ''+ '' ); $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code ==5){ $(pop_this).attr('href',"/login/index.html"); return false } if(data.code == 2){ //跳转到VIP升级页面 window.location.href="//m.obk20.com/vip/index?aid=" + webid return false } //是会员 if (data.code > 0) { $('body').append(htmlSetNormalDownload); var getWidth=$("#poplayer").width(); $("#poplayer").css("margin-left","-"+getWidth/2+"px"); $('#tips').html(data.msg) $('.download_confirm').click(function(){ $('#dialog').remove(); }) } else { var down_url = $('#vipdownload').attr('data-url'); isBindAnalysisForm(pop_this, down_url, 1) } }); }); //是否开通VIP $.get('/article/vipdownload/aid/'+webid,function(data){ if(data.code == 2 || data.code ==5){ //跳转到VIP升级页面 $('#vipdownload>span').text("开通VIP 免费下载") return false }else{ // 待续费 if(data.code == 3) { vipExpiredInfo.ifVipExpired = true vipExpiredInfo.vipExpiredDate = data.data.endoftime } $('#vipdownload .icon-vip-tips').remove() $('#vipdownload>span').text("VIP免积分下载") } }); }).on("click",".download_cancel",function(){ $('#dialog').remove(); }) var setWeixinShare={};//定义默认的微信分享信息,页面如果要自定义分享,直接更改此变量即可 if(window.navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){ var d={ title:'Alexa控制的乐高生物实验',//标题 desc:$('[name=description]').attr("content"), //描述 imgUrl:'https://'+location.host+'/static/images/ele-logo.png',// 分享图标,默认是logo link:'',//链接 type:'',// 分享类型,music、video或link,不填默认为link dataUrl:'',//如果type是music或video,则要提供数据链接,默认为空 success:'', // 用户确认分享后执行的回调函数 cancel:''// 用户取消分享后执行的回调函数 } setWeixinShare=$.extend(d,setWeixinShare); $.ajax({ url:"//www.obk20.com/app/wechat/index.php?s=Home/ShareConfig/index", data:"share_url="+encodeURIComponent(location.href)+"&format=jsonp&domain=m", type:'get', dataType:'jsonp', success:function(res){ if(res.status!="successed"){ return false; } $.getScript('https://res.wx.qq.com/open/js/jweixin-1.0.0.js',function(result,status){ if(status!="success"){ return false; } var getWxCfg=res.data; wx.config({ //debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。 appId:getWxCfg.appId, // 必填,公众号的唯一标识 timestamp:getWxCfg.timestamp, // 必填,生成签名的时间戳 nonceStr:getWxCfg.nonceStr, // 必填,生成签名的随机串 signature:getWxCfg.signature,// 必填,签名,见附录1 jsApiList:['onMenuShareTimeline','onMenuShareAppMessage','onMenuShareQQ','onMenuShareWeibo','onMenuShareQZone'] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 }); wx.ready(function(){ //获取“分享到朋友圈”按钮点击状态及自定义分享内容接口 wx.onMenuShareTimeline({ title: setWeixinShare.title, // 分享标题 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享给朋友”按钮点击状态及自定义分享内容接口 wx.onMenuShareAppMessage({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 type: setWeixinShare.type, // 分享类型,music、video或link,不填默认为link dataUrl: setWeixinShare.dataUrl, // 如果type是music或video,则要提供数据链接,默认为空 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ”按钮点击状态及自定义分享内容接口 wx.onMenuShareQQ({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口 wx.onMenuShareWeibo({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); //获取“分享到QQ空间”按钮点击状态及自定义分享内容接口 wx.onMenuShareQZone({ title: setWeixinShare.title, // 分享标题 desc: setWeixinShare.desc, // 分享描述 link: setWeixinShare.link, // 分享链接 imgUrl: setWeixinShare.imgUrl, // 分享图标 success: function () { setWeixinShare.success; // 用户确认分享后执行的回调函数 }, cancel: function () { setWeixinShare.cancel; // 用户取消分享后执行的回调函数 } }); }); }); } }); } function openX_ad(posterid, htmlid, width, height) { if ($(htmlid).length > 0) { var randomnumber = Math.random(); var now_url = encodeURIComponent(window.location.href); var ga = document.createElement('iframe'); ga.src = 'https://www1.elecfans.com/www/delivery/myafr.php?target=_blank&cb=' + randomnumber + '&zoneid=' + posterid+'&prefer='+now_url; ga.width = width; ga.height = height; ga.frameBorder = 0; ga.scrolling = 'no'; var s = $(htmlid).append(ga); } } openX_ad(828, '#berry-300', 300, 250);