Ophone平台蓝牙编程之蓝牙聊天分析(一)
OPhone平台开发, 2010-10-25 16:39:52
标签: OPhone 蓝牙编程
上一篇文章我们分析了Ophone平台的蓝牙开发包,本文我们将通过学习android的蓝牙聊天示例应用程序来介绍蓝牙开发包的使用,该示例程序完整的包含了蓝牙开发的各个部分,将实现两个设备通过蓝牙进行连接并聊天。
AndroidManifest.xml
前面我们说过,在使用蓝牙API时就需要开启某些权限,同时我们还可以从AndroidManifest.xml文件中找到应用程序启动时所进入的界面Activity等信息,因此下面我们首先打开AndroidManifest.xml文件,代码如下:
view plaincopy to clipboardprint?
1. 2.package="com.example.android.BluetoothChat" 3.android:versionCode="1" 4.android:versionName="1.0"> 5.> 6. 7.> 8. 9. 10. 11. 12.android:icon="@drawable/app_icon" > 13.> 14. 15.android:label="@string/app_name" 16.android:configChanges="orientation|keyboardHidden"> 17. 18. 19. 20. 21. 22. 23. 24.android:label="@string/select_device" 25.android:theme="@android:style/Theme.Dialog" 26.android:configChanges="orientation|keyboardHidden" /> 27. 28.
首先minSdkVersion用于说明该应用程序所需要使用的最小SDK版本,这里设置为6,也就是说最小需要使用android1.6版本的sdk,同时Ophone则需要使用oms2.0版本,然后打开了BLUETOOTH和BLUETOOTH_ADMIN两个蓝牙操作相关的权限,最后看到了两个Activity 的声明,他们分别是BluetoothChat(默认主Activity)和DeviceListActivity(显示设备列表),其中DeviceListActivity风格被定义为一个对话框风格,下面我们将分析该程序的每个细节。
BluetoothChat
首先,程序启动进入BluetoothChat,在onCreate函数中对窗口进行了设置,代码如下:view plaincopy to clipboardprint?
1.// 设置窗口布局
2.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
3.setContentView(https://www.doczj.com/doc/7a17661095.html,yout.main);
4.
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, https://www.doczj.com/doc/7a17661095.html,yout.cu
stom_title);
这里可以看到将窗口风格设置为自定义风格了,并且指定了自定义title布局为custom_title,其定义代码如下:
view plaincopy to clipboardprint?
1. 2.android:layout_width="match_parent" 3.android:layout_height="match_parent" 4.android:gravity="center_vertical" 5.> 6. 7.android:layout_alignParentLeft="true" 8.android:ellipsize="end" 9.android:singleLine="true" 10.style="?android:attr/windowTitleStyle" 11.android:layout_width="wrap_content" 13.android:layout_weight="1" 14./> 15. 16.android:layout_alignParentRight="true" 17.android:ellipsize="end" 18.android:singleLine="true" 19.android:layout_width="wrap_content" 20.android:layout_height="match_parent" 21.android:textColor="#fff" 22.android:layout_weight="1" 23./> 24.
该布局将title设置为一个相对布局RelativeLayout,其中包含了两个TextView,一个在左边一个在右边,分别用于显示应用程序的标题title和当前的蓝牙配对链接名称,如下图所示。
其中左边显示为应用程序名称"BluetoothChat",右边显示一个connected:scort则表示当前配对成功正在进行聊天的链接名称。整个聊天界面的布局在main.xml中实现,代码如下:
view plaincopy to clipboardprint?
1. 2.android:orientation="vertical" 3.android:layout_width="match_parent" 4.android:layout_height="match_parent" 5.> 6. 7. 8.android:layout_width="match_parent" 9.android:layout_height="match_parent" 10.android:stackFromBottom="true" 11.android:transcriptMode="alwaysScroll" 12.android:layout_weight="1" 13./> 14. 15. 16.android:orientation="horizontal" 18.android:layout_height="wrap_content" 19.> 20. 21.android:layout_width="wrap_content" 22.android:layout_height="wrap_content" 23.android:layout_weight="1" 24.android:layout_gravity="bottom" 25./> 26. 32.
整个界面的布局将是一个线性布局LinearLayout,其中包含了另一个ListView(用于显示聊天的对话信息)和另外一个线性布局来实现一个发送信息的窗口,发送消息发送框有一个输入框和一个发送按钮构成。整个界面如下图所示。
布局好界面,下面我们需要进入编码状态,首先看BluetoothChat所要那些成员变量,如下代码所示:
view plaincopy to clipboardprint?
1.public class BluetoothChat extends Activity {
2.// Debugging
3.private static final String TAG = "BluetoothChat";
4.private static final boolean D = true;
5.
6.//从BluetoothChatService Handler发送的消息类型
7.public static final int MESSAGE_STATE_CHANGE = 1;
8.public static final int MESSAGE_READ = 2;
9.public static final int MESSAGE_WRITE = 3;
10.public static final int MESSAGE_DEVICE_NAME = 4;
11.public static final int MESSAGE_TOAST = 5;
12.
13.// 从BluetoothChatService Handler接收消息时使用的键名(键-值模型)
14.public static final String DEVICE_NAME = "device_name";
15.public static final String TOAST = "toast";
16.
17.// Intent请求代码(请求链接,请求可见)
18.private static final int REQUEST_CONNECT_DEVICE = 1;
19.private static final int REQUEST_ENABLE_BT = 2;
20.
21.// Layout Views
22.private TextView mTitle;
23.private ListView mConversationView;
24.private EditText mOutEditText;
25.private Button mSendButton;
26.
27.// 链接的设备的名称
28.private String mConnectedDeviceName = null;
29.// Array adapter for the conversation thread
30.private ArrayAdapter
31.// 将要发送出去的字符串
32.private StringBuffer mOutStringBuffer;
33.// 本地蓝牙适配器
34.private BluetoothAdapter mBluetoothAdapter = null;
35.// 聊天服务的对象
36.private BluetoothChatService mChatService = null;
37.//......
其中Debugging部分则将用于我们在调试程序时通过log打印日志用,其他部分我们都加入了注释,需要说明的是BluetoothChatService ,它是我们自己定义的一个用来管理蓝牙的端口监听,链接,管理聊天的程序,后面我们会介绍。在这里需要说明一点,这些代码都出自google 的员工之手,大家在学习时,可以借鉴很多代码编写的技巧和风格,这都将对我们有非常大的帮助。
然后,我们就需要对界面进行一些设置,如下代码将用来设置我们自定义的标题title需要显示的内容:
view plaincopy to clipboardprint?
1.// 设置自定义title布局
2.mTitle = (TextView) findViewById(R.id.title_left_text);
3.mTitle.setText(R.string.app_name);
4.mTitle = (TextView) findViewById(R.id.title_right_text);
左边的TextView被设置为显示应用程序名称,右边的则需要我们在链接之后在设置更新,目前则显示没有链接字样,所以这里我们暂不设置,进一步就需要获取本地蓝牙适配器
BluetoothAdapter了,因为对于有关蓝牙的任何操作都需要首先获得该蓝牙适配器,获取代码非常简单,如下:
view plaincopy to clipboardprint?
1.// 得到一个本地蓝牙适配器
2.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
3.
4.// 如果适配器为null,则不支持蓝牙
5.if (mBluetoothAdapter == null) {
6.
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).s how();
7.finish();
8.return;
9.}
10.getDefaultAdapter()函数用于获取本地蓝牙适配器,然后检测是否为null,如
果为null则表示没有蓝牙设备的支持,将通过toast告知用户。
11.在onStart()函数中,我们将检测蓝牙是否被打开,如果没有打开,则请求打开,
否则就可以设置一些聊天信息的准备工作,代码如下:
12.@Override
13.public void onStart() {
14.super.onStart();
15.if(D) Log.e(TAG, "++ ON START ++");
16.
17.// 如果蓝牙没有打开,则请求打开
18.// setupChat() will then be called during onActivityResult
19.if (!mBluetoothAdapter.isEnabled()) {
20.
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_E
NABLE);
21.startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
22.// 否则,设置聊天会话
23.} else {
24.if (mChatService == null) setupChat();
25.}
26.}
如果蓝牙没有打开,我们则通过BluetoothAdapter.ACTION_REQUEST_ENABLE来请求打开蓝牙,REQUEST_ENABLE_BT则是我们自己定义的用于请求打开蓝牙的Intent代码,最后当我们调用startActivityForResult来执行请求时,就会在onActivityResult函数中得到一个反
馈,如果当前蓝牙已经打开,那么就可以调用setupChat函数来准备蓝牙聊天相关的工作,稍后分析该函数的具体实现。
下面我们分析一下请求打开蓝牙之后,在onActivityResult 中得到的反馈信息,我们传递了REQUEST_ENABLE_BT代码作为请求蓝牙打开的命令,因此在onActivityResult 中,需要会得到一个请求代码为REQUEST_ENABLE_B的消息,对于其处理如下代码所示:
view plaincopy to clipboardprint?
1.case REQUEST_ENABLE_BT:
2.// 在请求打开蓝牙时返回的代码
3.if (resultCode == Activity.RESULT_OK) {
4.// 蓝牙已经打开,所以设置一个聊天会话
5.setupChat();
6.} else {
7.// 请求打开蓝牙出错
8.Log.d(TAG, "BT not enabled");
9.
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SH ORT).show();
10.finish();
11.}
在请求时,如果返回代码为Activity.RESULT_OK,则表示请求打开蓝牙成功,那么我们就可以和上面的操作进度一样,调用setupChat来设置蓝牙聊天相关信息,如果返回其他代码,则表示请求打开蓝牙失败,这时我们同样通过一个Toast来告诉用户,同时也需要调用finish()函数来结束应用程序。
如果打开蓝牙无误,那么下面我们开始进入setupChat的设置,其代码实现如下:
view plaincopy to clipboardprint?
1.private void setupChat() {
2.Log.d(TAG, "setupChat()");
3.
4.// 初始化对话进程
5.
mConversationArrayAdapter = new ArrayAdapter
message);
6.// 初始化对话显示列表
7.mConversationView = (ListView) findViewById(R.id.in);
8.// 设置话显示列表源
9.mConversationView.setAdapter(mConversationArrayAdapter);
10.
11.// 初始化编辑框,并设置一个监听,用于处理按回车键发送消息
12.mOutEditText = (EditText) findViewById(R.id.edit_text_out);
13.mOutEditText.setOnEditorActionListener(mWriteListener);
14.
15.// 初始化发送按钮,并设置事件监听
16.mSendButton = (Button) findViewById(R.id.button_send);
17.mSendButton.setOnClickListener(new OnClickListener() {
18.public void onClick(View v) {
19.// 取得TextView中的内容来发送消息
20.TextView view = (TextView) findViewById(R.id.edit_text_out);
21.String message = view.getText().toString();
22.sendMessage(message);
23.}
24.});
25.
26.// 初始化BluetoothChatService并执行蓝牙连接
27.mChatService = new BluetoothChatService(this, mHandler);
28.
29.// 初始化将要发出的消息的字符串
30.mOutStringBuffer = new StringBuffer("");
31.}
首先构建一个对话进程mConversationArrayAdapter,然后从xml中取得用于显示对话信息的列表mConversationView,最后将列表的数据来源Adapter设置为mConversationArrayAdapter,这里我们可以看到mConversationArrayAdapter所指定的资源为message.xml,其定义实现如下:
view plaincopy to clipboardprint?
1. 2.android:layout_width="match_parent" 3.android:layout_height="wrap_content" 4.android:textSize="18sp" 5.android:padding="5dp" 6./> 很简单,就包含了一个TextView用来显示对话内容即可,这里设置了文字标签的尺寸大小textSize和padding属性。 然后我们取得了编辑框mOutEditText,用于输入聊天内容的输入框,并对其设置了一个事件监听mWriteListener,其监听函数的实现如下: view plaincopy to clipboardprint? 1.// The action listener for the EditText widget, to listen for the return key 2.private TextView.OnEditorActionListener mWriteListener = 3.new TextView.OnEditorActionListener() { 4. public boolean onEditorAction(TextView view, int actionId, KeyEvent eve nt) { 5.// 按下回车键并且是按键弹起的事件时发送消息 6. if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.A CTION_UP) { 7.String message = view.getText().toString(); 8.sendMessage(message); 9.} 10.if(D) Log.i(TAG, "END onEditorAction"); 11.return true; 12.} 13.}; 首先在其监听中实现了onEditorAction函数,我们通过判断其参数actionId来确定事件触发的动作,其中的"EditorInfo.IME_NULL"在Ophone中表示回车键消息,然后再加上KeyEvent.ACTION_UP,则表示当用户按下回车键并弹起时才触发消息的处理,处理过程也很简单,将输入框中内容取出到变量message中,然后调用sendMessage函数来发送一条消息,具体的发送细节,我们稍后分析。 在setupChat函数中,我们还对发送消息的按钮进行的初始化,同样为其设置了事件监听(setOnClickListener),监听的内容则也是取得输入框中的信息,然后调用sendMessage函数来发送消息,和用户按回车键来发送消息一样。 最后一个重要的操作就是初始化了BluetoothChatService对象mChatService用来管理蓝牙的链接,聊天的操作,并且设置了其Handler对象mHandler来负责数据的交换和线程之间的通信。另外还准备了一个空的字符串对象mOutStringBuffer,用于当我们在发送消息之后,对输入框的清理。 应用菜单 该应用程序除了这些界面的布局之外,我们还为其设置了一个菜单,菜单包括了"扫描设备"和"使设备可见(能够被其他设备所搜索到)",创建菜单的方式有很多种,这里gogole的员工, 比较喜欢和推崇使用xml布局(将界面和逻辑分开),所以我们首先看一下对于该应用程序通过xml所定义的菜单布局,代码如下: view plaincopy to clipboardprint? 1.
2.
3. 4.android:icon="@android:drawable/ic_menu_search" 5.android:title="@string/connect" /> 6. 7. 8.android:icon="@android:drawable/ic_menu_mylocation" 9.android:title="@string/discoverable" /> 10. 这样的定义的确非常的清晰,我们可以随意向这个Menu中添加菜单选项(itme),这里就定义了上面我们所说的两个菜单。然后再程序中通过onCreateOptionsMenu函数中来装载该菜单布局,遂于菜单的点击可以通过onOptionsItemSelected函数的不同参数来辨别,下面是该应用程序中对菜单选项的处理和装载菜单布局: view plaincopy to clipboardprint? 1.//创建一个菜单 2.@Override 3.public boolean onCreateOptionsMenu(Menu menu) { 4.MenuInflater inflater = getMenuInflater(); 5.inflater.inflate(R.menu.option_menu, menu); 6.return true; 7.} 8.//处理菜单事件 9.@Override 10.public boolean onOptionsItemSelected(MenuItem item) { 11.switch (item.getItemId()) { 12.case R.id.scan: 13.// 启动DeviceListActivity查看设备并扫描 14.Intent serverIntent = new Intent(this, DeviceListActivity.class); 15.startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE); 16.return true; 17.case R.id.discoverable: 18.// 确保设备处于可见状态 19.ensureDiscoverable(); 20.return true; 21.} 22.return false; 23.} 装载菜单布局的时候使用了MenuInflater对象,整个过程很简单,大家可以参考上面的代码实现,在处理菜单事件的时候,通过item.getItemId()我们可以得到当前选择的菜单项的ID,首先是扫描设备(R.id.scan),这里我们有启动了另外一个Activity来专门处理扫描设备DeviceListActivity,如果扫描之后我们将通过startActivityForResult函数来请求链接该设备,同样我们也会在onActivityResult函数中收到一个反馈信息,命令代码为 REQUEST_CONNECT_DEVICE,如果反馈的请求代码为Activity.RESULT_OK,则表示扫描成功(扫描过程我们稍后介绍),那么下面就可以开始准备链接了,实现代码如下: view plaincopy to clipboardprint? 1.case REQUEST_CONNECT_DEVICE: 2.// 当DeviceListActivity返回设备连接 3.if (resultCode == Activity.RESULT_OK) { 4.// 从Intent中得到设备的MAC地址 5.String address = data.getExtras() 6..getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS); 7.// 得到蓝牙设备对象 8. BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); 9.// 尝试连接这个设备 10.mChatService.connect(device); 11.} 12.break; 首先我们可以通过DeviceListActivity.EXTRA_DEVICE_ADDRESS来取得设备的Mac地址,然后通过Mac地址使用蓝牙适配器mBluetoothAdapter的getRemoteDevice函数来查找到该地址的设备BluetoothDevice,查询到之后我们可以通过mChatService对象的connect来链接该设备。 上面我们说的是扫描蓝牙设备并链接的过程,一般蓝牙设备在打开之后都需要设置可见状态,下面我们来看一下另一个菜单选项的实现,用于使设备处于可见状态,其菜单项的ID为R.id.discoverable,具体实现过程则位于ensureDiscoverable函数中,其实现如下代码: view plaincopy to clipboardprint? 1.private void ensureDiscoverable() { 2.if(D) Log.d(TAG, "ensure discoverable"); 3.//判断扫描模式是否为既可被发现又可以被连接 4.if (mBluetoothAdapter.getScanMode() != 5.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { 6.//请求可见状态 7. Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUE ST_DISCOVERABLE); 8.//添加附加属性,可见状态的时间 9. discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DU RATION, 300); 10.startActivity(discoverableIntent); 11.} 12.} 这里首先通过mBluetoothAdapter.getScanMode()函数取得该蓝牙的扫描模式,然后通过BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE设置可见属性,在这里我们加入一个附加属性BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,用来设置可见状态的时间,表示在指定的时间中蓝牙处于可见状态,设置好之后通过startActivity来执行即可。 这里忧一个需要注意的问题,在链接某个设备之前,我们需要开启一个端口监听,该应用程序将其放在onResume()函数中来处理了,代码如下: view plaincopy to clipboardprint? 1.@Override 2.public synchronized void onResume() { 3.super.onResume(); 4.if(D) Log.e(TAG, "+ ON RESUME +"); 5. 6. // Performing this check in onResume() covers the case in which BT was 7.// not enabled during onStart(), so we were paused to enable it... 8. // onResume() will be called when ACTION_REQUEST_ENABLE activity ret urns. 9.if (mChatService != null) { 10.// 如果当前状态为STATE_NONE,则需要开启蓝牙聊天服务 11. if (mChatService.getState() == BluetoothChatService.STATE_NONE) { 12.// 开始一个蓝牙聊天服务 13.mChatService.start(); 14.} 15.} 16.} 首先检测mChatService是否被初始化,然后检测其状态是否为STATE_NONE, STATE_NONE表示初始化之后处于等待的状态,当我们在setupChat函数中初始时,其实就已经将其状态设置为STATE_NONE了(该操作是在BluetoothChatService的构造函数中处理的),所以这里就可以通过一个start函数来启动一个进程即可,实际上就是启动了一个端口监听进程,当有设备连接时,该监听进程结束,然后转向链接进程,链接之后同样又将转换到一个聊天管理进程,对于这些链接过程和通信模块看来只有下一篇文章介绍了,准备睡觉,明天还得上班!哎... 总结 本文试图完成一个蓝牙聊天程序的分析和实现,但是我发现只要涉及网络通信模块的程序分析过程都比较复杂,可能是因为分析太细的原因,并没有分析完该程序,因此,下一篇文章我们继续分析,同时下一篇要介绍的也是最核心的内容,网络通信过程,希望能得到大家的支持。! 作者介绍 刘子奇(万游数字) (声明:本网的新闻及文章版权均属OPhone SDN网站所有,如需转载请与我们编辑团队联系。任何媒体、网站或个人未经本网书面协议授权,不得进行任何形式的转载。已经取得本网协议授权的媒体、网站,在转载使用时请注明稿件来源。) function nijiede a2=431.8; a3=20.32; d2=149.09; d4=433.07; nx=0;ny=0;nz=1; ax=0;ay=1;az=0; px=-149.09;py=864.87;pz=20.32; t1=[(atan2(py,px)-atan2(d2,sqrt(px^2+py^2-d2^2))),(atan2(py,px)-atan2(d 2,-sqrt(px^2+py^2-d2^2)))]; k=(px^2+py^2+pz^2-a2^2-a3^2-d2^2-d4^2)/(2*a2); k1=atan2(a3,d4); t3=[(k1-atan2(k,sqrt(a3^2+d4^2-k^2))),(k1-atan2(k,-sqrt(a3^2+d4^2-k^2)) )]; for i=1:2; for j=1:2; t2=atan2(-(a3+a2*cos(t3(j)))*pz+(cos(t1(i))*px+sin(t1(i))*py)*(a2*sin(t 3(j))-d4),... (-d4+a2*sin(t3(j)))*pz+(cos(t1(i))*px+sin(t1(i))*py)*(a2*cos(t3(j))+a3) )-t3(j); for n=1:2; t4=atan2((-1)^(n+1)*(-ax*sin(t1(i))+ay*cos(t1(i))),(-1)^(n+1)*(-ax*cos( t1(i))*cos(t2+t3(j))-ay*sin(t1(i))*cos(t2+t3(j))+az*sin(t2+t3(j)))); s5=-ax*(cos(t1(i))*cos(t2+t3(j))*cos(t4)+sin(t1(i))*sin(t4))... -ay*(sin(t1(i))*cos(t2+t3(j))*cos(t4)-cos(t1(i))*sin(t4))... +az*(sin(t2+t3(j))*cos(t4)); c5=ax*(-cos(t1(i))*sin(t2+t3(j)))+ay*(-sin(t1(i))*sin(t2+t3(j)))+az*(-c os(t2+t3(j))); t5=atan2(s5,c5); s6=-nx*(cos(t1(i))*cos(t2+t3(j))*sin(t4)-sin(t1(i))*cos(t4))... -ny*(sin(t1(i))*cos(t2+t3(j))*sin(t4)+cos(t1(i))*cos(t4))+nz*(sin(t2+t3 (j))*sin(t4)); c6=nx*((cos(t1(i))*cos(t2+t3(j))*cos(t4)+sin(t1(i))*sin(t4))*cos(t5)-co s(t1(i))*sin(t2+t3(j))*sin(t5))... +ny*((sin(t1(i))*cos(t2+t3(j))*cos(t4)-cos(t1(i))*sin(t4))*cos(t5)-sin( t1(i))*sin(t2+t3(j))*sin(t5))... -nz*(sin(t2+t3(j))*cos(t4)*cos(t5)+cos(t2+t3(j))*sin(t5)); t6=atan2(s6,c6); %t2=round(t2*180/pi) t=round([t1(i),t2,t3(j),t4,t5,t6]*180/pi); %disp(t); if(t(1)>-160)&&(t(1)<160)&&(t(2)>-225)&&(t(2)<45)&&(t(3)>-225)&&(t(3)<4 5)&&(t(4)>-110)&&(t(4)<170)&&(t(5)>-100)&&(t(5)<100)&&(t(6)>-266)&&(t(6 )<266) if ABB[a]-J-6ABB机器人的程序编程 6.1任务目标 ?掌握常用的PAPID程序指令。 ?掌握基本RAPID程序编写、调试、自动运行和保存模块。 6.2任务描述 ◆建立程序模块test12.24,模块test12.24下建立例行程序main和Routine1,在main程序下进行运动指 令的基本操作练习。 ◆掌握常用的RAPID指令的使用方法。 ◆建立一个可运行的基本RAPID程序,内容包括程序编写、调试、自动运行和保存模块。 6.3知识储备 6.3.1程序模块与例行程序 RAPID程序中包含了一连串控制机器人的指令,执行这些指令可以实现对机器人的控制操作。 应用程序是使用称为RAPID编程语言的特定词汇和语法编写而成的。RAPID是一种英文编程语言,所包含的指令可以移动机器人、设置输出、读取输入,还能实现决策、重复其他指令、构造程序、与系统操作员交流等功能。RAPID程序的基本架构如图所示: RAPID程序的架构说明: 1)RAPID程序是由程序模块与系统模块组成。一般地,只通过新建程序模块来构建机器人的程序,而系统模块多用于系统方面的控制。 2)可以根据不同的用途创建多个程序模块,如专门用于主控制的程序模块,用于位置计算的程序模块,用于存放数据的程序模块,这样便于归类管理不同用途的例行程序与数据。 3)每一个程序模块包含了程序数据、例行程序、中断程序和功能四种对象,但不一定在一个模块中都有这四种对象,程序模块之间的数据、例行程序、中断程序和功能是可以互相调用的。 4)在RAPID程序中,只有一个主程序main,并且存在于任意一个程序模块中,并且是作为整个RAPID 程序执行的起点。 操作步骤: 1.单击“程序编辑器”,查看 RAPID程序。 2.单击“例行程序”,查看例行 程序列表。 3.单击“后退”或“模块”标签查 看模块列表。 4.在“模块”和“例行程序”视图 中,可以点击“文件”—“新建” 去建立模块或例行程序。 6.3.2在示教器上进行指令编程的基本操作 ABB机器人的RAPID编程提供了丰富的指令来完成各种简单与复杂的应用。下面就从最常用的指令开始学习RAPID编程,领略RAPID丰富的指令集提供的编程便利性。 ABB[a]-J-6ABB 机器人的程序编程 6.1 任务目标 ?掌握常用的PAPID 程序指令。 ?掌握基本RAPID程序编写、调试、自动运行和保存模块。 6.2 任务描述 ◆建立程序模块test12.24,模块test12.24 下建立例行程序main 和Routine1,在main 程序下进行运动指 令的基本操作练习。 ◆掌握常用的RAPID 指令的使用方法。 ◆建立一个可运行的基本RAPID程序,内容包括程序编写、调试、自动运行和保存模块。 6.3 知识储备 6.3.1 程序模块与例行程序 RAPID 程序中包含了一连串控制机器人的指令,执行这些指令可以实现对机器人的控制操作。应用程序是使用称为RAPID 编程语言的特定词汇和语法编写而成的。RAPID 是一种英文编程语言,所包 含的指令可以移动机器人、设置输出、读取输入,还能实现决策、重复其他指令、构造程序、与系统操作 RAPID 程序的架构说明: 1)RAPID 程序是由程序模块与系统模块组成。一般地,只通过新建程序模块来构建机器人的程序,而系统模块多用于系统方面的控制。 2)可以根据不同的用途创建多个程序模块,如专门用于主控制的程序模块,用于位置计算的程序模块,用于存放数据的程序模块,这样便于归类管理不同用途的例行程序与数据。 3)每一个程序模块包含了程序数据、例行程序、中断程序和功能四种对象,但不一定在一个模块中都 1文档来源为:从网络收集整理.word版本可编辑. 有这四种对象,程序模块之间的数据、例行程序、中断程序和功能是可以互相调用的。 4)在RAPID 程序中,只有一个主程序main,并且存在于任意一个程序模块中,并且是作为整个RAPID 程序执行的起点。 操作步骤: 6.3.2 在示教器上进行指令编程的基本操作 ABB 机器人的RAPID 编程提供了丰富的指令来完成各种简单与复杂的应用。下面就从最常用的指令开始 2文档来源为:从网络收集整理.word版本可编辑. 机器人编程的三种主要方式 内容来源网络,由“深圳机械展(11万㎡,1100多家展商,超10万观众)”收集整理! 更多cnc加工中心、车铣磨钻床、线切割、数控刀具工具、工业机器人、非标自动化、数字化无人工厂、精密测量、3D打印、激光切割、钣金冲压折弯、精密零件加工等展示,就在深圳机械展. 从20世纪60年代工业机器人诞生以来,机器人应用程度和应用规模成为工业自动化水平的典型标志之一。我国是焊接机器人应用和需求大国,从80年代开始许多科研机构已经着手进行焊接机器人的研究,取得了长足的进步和发展,国内焊接机器人主要有两家制造公司,分别是新松机器人自动化股份有限公司和首钢莫托曼机器人有限公司。但是与欧美和口本等国家相比较,机器人的控制水平和可靠性能还存在一定差距,也还未形成一定的规模产业。焊接机器人作为一种可编程装置,按照其编程方式可分为示 教编程、离线编程和自主编程三种。 (1)示教编程 示教编程是指操作人员通过人工手动的方式,利用示教板移动机器人末端焊枪跟踪焊缝,适时记录焊件焊缝轨迹和焊接工艺参数,机器人根据记录信息采用逐点示教的方式再现焊接过程。这种逐点记录焊枪姿态再重现的方法需要操作人员充当外部传感的角色,机器人自身缺乏外部信息传感,灵活性较差,而且对于结构复杂的焊件,需要操作人员花费大量的时间进行示教,编程效率低。当焊接环境参数发生变化时,需要重新示教焊接过程,不能适应焊接对象和任务变化的场合,焊接精度差 (2)离线编程 离线编程采用部分传感技术,主要依靠计算机图形学技术,建立机器人工作模型,对编程结果进行三维图形学动画仿真以检测编程可靠性,最后将生成的代码传递给机器人控制柜控制机器人运行。与示教编程相比,离线编程可以减少机器人工作时间,结合CAD技术,简化编程。国外机器人离线编程技术研究成熟,各工业机器人产商都配有各自机器人专用的离线编程软件系统。比如ABB的Robot studio仿真编程软件,既可以做仿真分析又可以离线编程。离线编程能够构造模拟的焊接环境,依据工况条件,应用CAD技术构造相应的夹具、零件和工具的几何模型。但缺乏真实焊接环境的传感数据,所构造的几何模型对真实焊接目标也只是部分的描述,在焊接过程中必须做出偏差调 0.1 简述工业机器人的定义,说明机器人的主要特征。 答:机器人是一种用于移动各种材料、零件、工具、或专用装置,通过可编程动作来执行种种任务并具有编程能力的多功能机械手。 1.机器人的动作结构具有类似于人或其他生物体某些器官(肢体、感官等)的功能。 2.机器人具有通用性,工作种类多样,动作程序灵活易变。 3.机器人具有不同程度的智能性,如记忆、感知、推理、决策、学习等。 4.机器人具有独立性,完整的机器人系统在工作中可以不依赖于人的干预。 0.2工业机器人与数控机床有什么区别? 答:1.机器人的运动为开式运动链而数控机床为闭式运动链; 2.工业机器人一般具有多关节,数控机床一般无关节且均为直角坐标系统; 3.工业机器人是用于工业中各种作业的自动化机器而数控机床应用于冷加工。 4.机器人灵活性好,数控机床灵活性差。 0.5简述下面几个术语的含义:自有度、重复定位精度、工作范围、工作速度、承载能力。 答:自由度是机器人所具有的独立坐标运动的数目,不包括手爪(末端执行器)的开合自由度。 重复定位精度是关于精度的统计数据,指机器人重复到达某一确定位置准确的概率, 是重复同一位置的范围,可以用各次不同位置平均值的偏差来表示。 工作范围是指机器人手臂末端或手腕中心所能到达的所有点的集合,也叫工作区域。 工作速度一般指最大工作速度,可以是指自由度上最大的稳定速度,也可以定义为 手臂末端最大的合成速度(通常在技术参数中加以说明)。 承载能力是指机器人在工作范围内的任何位姿上所能承受的最大质量。 0.6什么叫冗余自由度机器人? 答:从运动学的观点看,完成某一特定作业时具有多余自由度的机器人称为冗余自由度机器人。 3.1 何谓轨迹规划?简述轨迹规划的方法并说明其特点。 答:机器人的轨迹泛指工业机器人在运动过程中的运动轨迹,即运动点位移,速度和加速度。 轨迹的生成一般是先给定轨迹上的若干个点,将其经运动学反解映射到关节空间,对关节空间中的相应点建立运动方程,然后按这些运动方程对关节进行插值,从而实现作业空间的运动要求,这一过程通常称为轨迹规划。 (1)示教—再现运动。这种运动由人手把手示教机器人,定时记录各关节变量,得到沿路径运动时各关节的位移时间函数q(t);再现时,按内存中记录的各点的值产生序列动作。 (2)关节空间运动。这种运动直接在关节空间里进行。由于动力学参数及其极限值直接在关节空间里描述,所以用这种方式求最短时间运动很方便。 ABB[a]-J-5ABB 机器人的程序数据 5.1 任务目标 掌握程序数据的建立方法。 掌握三个关键程序数据的设定。 了解机器人工具自动识别功能。 5.2 任务描述 ◆以bool 为例,建立程序数据,练习建立num、robtarget 程序数据。 ◆设定机器人的工具数据tooldata、工件坐标wobjdata、负荷数据loaddata。 ◆使用LoadIdentify 工具自动识别安装在六轴法兰盘上的工具(tooldata)和载荷(loaddata)的重量,以 及重心。 5.3 知识储备 5.3.1 程序数据 程序数据是在程序模块或系统模块中设定的值和定义的一些环境数据。创建的程序数据由同一个模块或其他模块中的指令进行引用。图中是一条常用的机器人关节运动的指令MoveJ,调用了四个程序数据。 图中所使用的程序数据的说明见表: 5.3.2 程序数据的类型与分类 1.程序数据的类型分类 ABB 机器人的程序数据共有76 个,并且可以根据实际情况进行程序数据的创建,为ABB 机器人的程序设计带来了无限可能性。 在示教器的“程序数据”窗口可查看和创建所需要的程序数据。 2.程序数据的存储类型 (1)变量VAR 变量型数据在程序执行的过程中和停止时,会保持当前的值。但如果程序指针被移到主程序后,数值会丢失。 举例说明: VAR num length:=0;名称为length 的数字数据 VAR string name:=”Jo hn”;名称为name 的字符数据 VAR bool finish:=FALSE;名称为finish 的布尔量数据 在程序编辑窗口中的显示如图: 在机器人执行的RAPID 程序中也可以对变量存储类型程序数据进行赋值的操作,如图: 智能小车前后左右综合实验 void left(int time) //左转(左轮不动,右轮前进) { digitalWrite(Right_motor_go,HIGH); // 右电机前进digitalWrite(Right_motor_back,LOW); analogWrite(Right_motor_go,200); analogWrite(Right_motor_back,0);//PWM比例0~255调速digitalWrite(Left_motor_go,LOW); //左轮不动digitalWrite(Left_motor_back,LOW); analogWrite(Left_motor_go,0); analogWrite(Left_motor_back,0);//PWM比例0~255调速delay(time * 100); //执行时间,可以调整 } void spin_left(int time) //左转(左轮后退,右轮前进) { digitalWrite(Right_motor_go,HIGH); // 右电机前进digitalWrite(Right_motor_back,LOW); analogWrite(Right_motor_go,200); analogWrite(Right_motor_back,0);//PWM比例0~255调速digitalWrite(Left_motor_go,LOW); //左轮后退digitalWrite(Left_motor_back,HIGH); analogWrite(Left_motor_go,0); analogWrite(Left_motor_back,200);//PWM比例0~255调速delay(time * 100); //执行时间,可以调整 } void right(int time) //右转(右轮不动,左轮前进) A B B[a]-J-6A B B机器人的程序编程 6.1 任务目标 ?掌握常用的PAPID 程序指令。 ?掌握基本RAPID程序编写、调试、自动运行和保存模块。 6.2 任务描述 ◆建立程序模块test12.24,模块test12.24 下建立例行程序main 和Routine1,在main 程序下进行运动指 令的基本操作练习。 ◆掌握常用的RAPID 指令的使用方法。 ◆建立一个可运行的基本RAPID程序,内容包括程序编写、调试、自动运行和保存模块。 6.3 知识储备 6.3.1 程序模块与例行程序 RAPID 程序中包含了一连串控制机器人的指令,执行这些指令可以实现对机器人的控制操作。应用程序是使用称为RAPID 编程语言的特定词汇和语法编写而成的。RAPID 是一种英文编程语言,所包 含的指令可以移动机器人、设置输出、读取输入,还能实现决策、重复其他指令、构造程序、与系统操作员交流等功能。RAPID 程序的基本架构如图所示: RAPID 程序的架构说明: 1)RAPID 程序是由程序模块与系统模块组成。一般地,只通过新建程序模块来构建机器人的程序,而系统模块多用于系统方面的控制。 2)可以根据不同的用途创建多个程序模块,如专门用于主控制的程序模块,用于位置计算的程序模块,用于存放数据的程序模块,这样便于归类管理不同用途的例行程序与数据。 3)每一个程序模块包含了程序数据、例行程序、中断程序和功能四种对象,但不一定在一个模块中都 有这四种对象,程序模块之间的数据、例行程序、中断程序和功能是可以互相调用的。 4)在RAPID 程序中,只有一个主程序main,并且存在于任意一个程序模块中,并且是作为整个RAPID 程序执行的起点。 操作步骤: 6.3.2 在示教器上进行指令编程的基本操作 ABB 机器人的RAPID 编程提供了丰富的指令来完成各种简单与复杂的应用。下面就从最常用的指令开始 跳舞机器人的实现源程序 一个典型的A型电机的加速过程amotor.asm程序清单: ;该程序用来驱动A型电机左右各转120度 DRIVE: MOV 81H,#40H ;避免堆栈指针的影响,81H为SP的物理地址ACALL INIT ;调用初始化子程序 MOV D PTR,#004FH ;DPTR指向数据表 MOV R0,05H ;开始为向右转,05H为R5的物理地址TURN: CLR A MOVC A,@A+DPTR ;取脉冲数 MOV R3,A ;R3存每阶段的脉冲数 STEP: MOV A,#0FH MOVC A,@A+DPTR ;取该阶段的延时数 MOV R4,A ;延时数存R4中 CJNE @R0,#00H,NEXT ;状态字指针R0到尽头 MOV R0,05H ;指针复位 NEXT: MOV 80H,@R0 ;输出脉冲,89H为P2口的物理地址 MOV 90H,@R0 MOV 0A0H,@R0 MOV 0B0H,@R0 INC R0 ;指针下移 ACALL DELAY ;延时 DJNZ R3,STEP ;该阶段循环 INC D PTR DJNZ R2,TURN ;执行下一阶段 DEC R6 MOV A,R6 JZ STOP ;总步数结束 MOV R7,#40 REST: MOV R4,#0FFH ;正转120度,休息 ACALL DELAY DJNZ R7,REST MOV R2,#0FH ;加速阶段数复位 MOV D PTR,#004FH ;DPTR复位 CJNE R5,#20H,RIGHT ;R5存正反状态字 LEFT: MOV R5,#25H MOV R0,05H SJMP TURN RIGHT: MOV R5,#20H MOV R0,05H SJMP TURN STOP: SJMP STOP ;停机 ; ORG 004FH PULETAB: D B 9,10,11,12,14,15,16,17 DB 18,19,108,108,108,108,108 TIMETAB: D B 55,50,45,42,36,33,31,29 DB 27,26,24,24,24,24,24 DELAY1: MOV 08H,#34 ;DELAY1为延时0.1MS的标准子程序 LOOP1: NOP DJNZ 08H,LOOP1 第一节图形化交互式C语言简介 4.1.1VJC简介 图形化交互式C语言(简称VJC)是用于能力风暴智能机器人系列产品的软件开发系统,具有基于流程图的编程语言和交互式C语言(简称JC)。VJC为开发智能机器人项目、程序与算法、教学等提供了简单而又功能强大的平台,是全球开创性的具有自主知识产权的产品。 在VJC中,不仅可以用直观的流程图编程,也可以用JC语言编写更高级的机器人程序。流程图和JC语言双剑合壁,既能领读者轻松入门,又能够让读者在编程中发挥最大的创造力。 VJC操作简便,有活泼明快的图案和简短的文字说明。读者可以使用形象化的模块,由顶向下搭建流程图,搭建流程图的同时,动态生成无语法错误的JC代码。流程图搭建完毕,程序就已经编写完成,可以立即下载到机器人中运行。已入门的读者可以直接在JC代码编辑环境中编写程序,还可以边写边试,发现错误,校正修改,十分方便。VJC能让你在丰富多彩的机器人世界里,边玩边学,愉快地掌握许多有用的科技知识。 用常规的计算机编程语言(如C、FORTRAN、JAVA)编程,需要输入复杂的程序代码,并且编写的程序还要符合特定的语法。而流程图编程不需要记忆计算机语言的语法,不需要使用键盘输入程序代码,只需要按照“先作什么,后作什么”的设想,就可以编出程序。VJC正是按这个思想设计的。使用VJC软件,学生们不用关心语言实现的细节,同时也有效避免了语法错误,有利于集中精力寻求解决问题的方法。 VJC的流程图模型由以下几种基本形状的模块及带有箭头的方向线组成: VJC的模块包括:执行器模块(蓝色矩形)、单功能传感器模块(紫色平行四边形)、带判断功能的传感器模块(紫色菱形)、控制模块(红色菱形)和程序模块(黄色矩形或椭圆形)五种。 VJC流程图支持多任务程序、子程序调用、浮点数和整数、全局变量、简单表达式、复合条件判断以及循环嵌套等。 A B B机器人的程序编程 集团标准化办公室:[VV986T-J682P28-JP266L8-68PNN] ABB[a]-J-6ABB 机器人的程序编程 任务目标 掌握常用的PAPID 程序指令。 掌握基本RAPID程序编写、调试、自动运行和保存模块。 任务描述 建立程序模块,模块下建立例行程序main 和Routine1,在main 程序下进行运动指令的基本操作练习。 掌握常用的RAPID 指令的使用方法。 建立一个可运行的基本RAPID程序,内容包括程序编写、调试、自动运行和保存模块。 知识储备 程序模块与例行程序 RAPID 程序中包含了一连串控制机器人的指令,执行这些指令可以实现对机器人的控制操作。应用程序是使用称为RAPID 编程语言的特定词汇和语法编写而成的。RAPID 是一种英文编程语言,所包 含的指令可以移动机器人、设置输出、读取输入,还能实现决策、重复其他指令、构造程序、与系统操作 员交流等功能。RAPID 程序的基本架构如图所示: RAPID 程序的架构说明: 1)RAPID 程序是由程序模块与系统模块组成。一般地,只通过新建程序模块来构建机器人的程序,而系统模块多用于系统方面的控制。 2)可以根据不同的用途创建多个程序模块,如专门用于主控制的程序模块,用于位置计算的程序模块,用于存放数据的程序模块,这样便于归类管理不同用途的例行程序与数据。 3)每一个程序模块包含了程序数据、例行程序、中断程序和功能四种对象,但不一定在一个模块中都 有这四种对象,程序模块之间的数据、例行程序、中断程序和功能是可以互相调用的。 4)在RAPID 程序中,只有一个主程序main,并且存在于任意一个程序模块中,并且是作为整个RAPID 程序执行的起 点。操作步骤: 码垛机器人程序代码 MODULE Module_stacking VAR num DN250:=0; VAR num DN300:=0; VAR num DN350:=0; VAR num DN400:=0; VAR num DN450:=0; VAR num DN500:=0; VAR num DN600:=0; VAR num DN700:=0; VAR num DN750:=0; VAR num DN800:=0; VAR num DN900:=0; VAR num DN1000:=0; VAR num singlelaxxxxyer_250:=4; VAR num singlelaxxxxyer_300:=4; VAR num singlelaxxxxyer_350:=3; VAR num singlelaxxxxyer_400:=3; VAR num singlelaxxxxyer_450:=3; VAR num singlelaxxxxyer_500:=4; VAR num singlelaxxxxyer_600:=2; VAR num singlelaxxxxyer_700:=2; VAR num singlelaxxxxyer_750:=1; VAR num singlelaxxxxyer_800:=1; VAR num singlelaxxxxyer_900:=1; VAR num singlelaxxxxyer_1000:=1; !.............................. VAR num Totallaxxxxyer_L_250:=5; VAR num Totallaxxxxyer_L_300:=5; VAR num Totallaxxxxyer_L_350:=5;机器人逆解MATLAB程序代码
最新ABB机器人的程序编程
ABB机器人的程序编程
机器人编程的三种主要方式
机器人参考答案
ABB机器人的程序数据资料
机器人源程序
ABB机器人的程序编程
跳舞机器人的实现源程序
能力风暴机器人编程
ABB机器人的程序编程
码垛机器人程序代码